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