以下无法在gcc和clang上编译
#include <type_traits>
int foo();
int main()
{
using R = std::result_of_t<decltype(foo)()>; // error
}
两个编译器的错误都是处理声明函数返回函数的非法性。但我并没有宣布这样的功能 - 我只是试图写出它的类型 - 因为那是result_of
所期望的。这真的还是不合格吗?
答案 0 :(得分:10)
您正在传递 type-id ,其在[dcl.name]中定义为
[...]语法上是该类型的变量或函数的声明,省略了实体的名称。 [...]可以唯一地标识 abstract-declarator 中的位置,如果构造是声明中的声明符,则标识符将出现。然后,命名类型与类型相同 假设标识符。
对于具有某种类型的假设标识符,假设声明必须首先是格式良好的。但它并不是[dcl.fct]/10。因此,程序是不正确的(编译器的错误消息实际上是可理解的)。 [temp.deduct]/(8.10)也更直接地涵盖了这种情况,这意味着这是一个(SFINAE友好的)错误。
事实上,仅仅暗示无效类型的使用就足以使程序格式错误。例如。创建函数返回函数的类型指针是不正确的:
using f = int();
using t = f(*)();
以下是:
struct A {virtual void f() = 0;};
using t = A(*)();
(Clang不应该接受这个.C。GCC bug 17232有趣的讨论)。