hutorny
hutorny

Reputation: 873

error: `type` in `class std::result_of` does not name a type

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

Answers (3)

Jonathan Mee
Jonathan Mee

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&>()));

Live Example

Upvotes: 1

max66
max66

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

T.C.
T.C.

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

Related Questions