Reputation: 873
Example below fails with all compilers I've tried: gcc-8.2, clang-8.0 (both options --std=c++17
and std=c++2a
were tried) and zapcc-2017.08.
From my point of view the code sample is valid and should be compiled. Or, at least, there should be a more comprehensive error. It does look like a bug in the std library, not covering this particular case for result_of
. Am I wrong?
#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;
Upvotes: 3
Views: 4055
Reputation: 38909
In my experience there really isn't anything that result_of
can do which decltype
cannot (or result_of_t
which would help simplify your code): How Can I Use result_of Instead of decltype?
That holds true in this case as well, where decltype
and declval
will give you a simpler result than result_of
:
using f = decltype(foo<&bar::a>::q(declval<bar&>()));
using q = decltype(qoo<&bar::a>(declval<bar&>()));
Upvotes: 1
Reputation: 66190
Try with
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;
As better explained by T.C., the type
in std::result_of
is the type returned from a type of a callable when called with some argument types.
If you write
std::result_of<decltype(foo<&bar::a>::q)>
you pass to std::result_of
only the type of the callable (almost: you also needs a &
before foo
); you also have to pass the type of the arguments (only one argument, in this case: a bar
reference), so
std::result_of<decltype(&foo<&bar::a>::q)(bar&)>
Upvotes: 3
Reputation: 137301
result_of_t<F(Args...)>
means "the result of calling/invoking F
with Args...
".
result_of_t<int(bar&)>
means "the result of calling int
with bar&
". Which doesn't exist because you can't call an int
with, well, anything.
result_of
is not "extract the return type from a function type".
Upvotes: 4