Пример ниже не работает со всеми компиляторами, которые я пробовал: gcc-8.2, clang-8.0 (были опробованы оба варианта --std=c++17 и std=c++2a) и zapcc-2017.08.
С моей точки зрения, образец кода действителен и должен быть скомпилирован. Или, по крайней мере, должна быть более серьезная ошибка. Это действительно похоже на ошибку в библиотеке std, не охватывающую этот конкретный случай для result_of. Я ошибся?
#include <type_traits>
using namespace std;
struct bar {
int a;
long b;
};
template<auto M>
struct foo {
static auto q(bar & b) {
return b.*M;
}
};
template<auto M>
auto qoo(bar & b) {
return b.*M;
}
// error: 'type' in 'class std::result_of<int(bar&)>' does not name a type
using f = typename result_of<decltype(foo<&bar::a>::q)>::type;
// error: 'type' in 'class std::result_of<int(bar&)>' does not name a type
using q= typename result_of<decltype(qoo<&bar::a>)>::type;
@ πάνταῥεῖ Вы находитесь в режиме C++ 11, из-за чего он не работает по совершенно другим причинам. Переведите его в режим C++ 17, и вы получите тот же результат, что и OP.
@LightnessRacesinOrbit Упс да.
@ Lightness Races на орбите - ни одна из пяти перечисленных здесь





result_of_t<F(Args...)> означает «результат вызова / вызова F с помощью Args...».
result_of_t<int(bar&)> означает «результат вызова int с помощью bar&». Этого не существует, потому что вы не можете вызвать на int, ну, с чем угодно.
result_of - это нет «извлечь тип возвращаемого значения из типа функции».
Попробуйте с
using f = typename std::result_of<decltype(&foo<&bar::a>::q)(bar&)>::type;
using q= typename std::result_of<decltype(&qoo<&bar::a>)(bar&)>::type;
Как лучше объяснил T.C., type в std::result_of - это тип, возвращаемый из типа вызываемого объекта при вызове с некоторыми типами аргументов.
Если вы напишете
std::result_of<decltype(foo<&bar::a>::q)>
вы передаете std::result_of только тип вызываемого (почти: вам также нужен & перед foo); вам также необходимо передать тип аргументов (в данном случае только один аргумент: ссылка на bar), поэтому
std::result_of<decltype(&foo<&bar::a>::q)(bar&)>
По моему опыту, result_of не может делать ничего такого, чего не может decltype (или result_of_t, что помогло бы упростить ваш код): Как я могу использовать result_of вместо decltype?
Это верно и в этом случае, когда decltype и declval дадут более простой результат, чем result_of:
using f = decltype(foo<&bar::a>::q(declval<bar&>()));
using q = decltype(qoo<&bar::a>(declval<bar&>()));
result_of необходим, если вы хотите поддерживать полный диапазон вызываемых объектов.
@ T.C. Я не могу придумать пример, для достижения которого я не смог бы использовать какую-либо комбинацию declval и decltype, но я хотел бы понять. Стоит ли мне задать еще один вопрос или есть простой пример, который вы могли бы дать в комментарии?
Полный набор вызываемых объектов включает указатели на члены.
@ T.C. Не могу ли я вызвать указатель на член с помощью declval? Например: ideone.com/25wpKD
Конечно. Теперь попробуйте написать тот, который работает для указателей оба на объекты функций а также членов.
Отвечает ли на ваш вопрос какая-либо из причуд, перечисленных в cppreference doc для
result_of?