Barry
Barry

Reputation: 303890

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?

Upvotes: 18

Views: 445

Answers (1)

Columbo
Columbo

Reputation: 61009

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).

Upvotes: 10

Related Questions