Search code examples
c++templatesc++17c++20result-of

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;

Solution

  • 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&)>