c++language-lawyerc++14result-of

Can I write a function type that returns a function?


The following fails to compile on both gcc and clang

#include <type_traits>

int foo();

int main()
{
    using R = std::result_of_t<decltype(foo)()>; // error
}

The error on both compilers deals with the illegality of declaring a function returning a function. But I'm not declaring such a function - I'm just trying to write its type - since that's what result_of expects. Is this really still ill-formed?


Solution

  • You're passing a type-id, which is defined in [dcl.name] as

    […] syntactically a declaration for a variable or function of that type that omits the name of the entity. […] It is possible to identify uniquely the location in the abstract-declarator where the identifier would appear if the construction were a declarator in a declaration. The named type is then the same as the type of the hypothetical identifier.

    For the hypothetical identifier to have some type, the hypothetical declaration must be well-formed in the first place. But it isn't as per [dcl.fct]/10. Hence the program is ill-formed (and the compilers' error messages are actually comprehensible). This case is also more directly covered by [temp.deduct]/(8.10), implying that this is a (SFINAE-friendly) error.


    In fact, merely implying an invalid type's usage suffices to make the program ill-formed. E.g. creating the type pointer to function returning function is ill-formed:

    using f = int();
    using t = f(*)();
    

    So is the following:

    struct A {virtual void f() = 0;};
    using t = A(*)();
    

    (Clang shouldn't be accepting this. C.f. GCC bug 17232's interesting discussion).