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