17

以下无法在 gcc 和 clang 上编译

#include <type_traits>

int foo();

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

两个编译器上的错误都涉及声明函数返回函数的非法性。但我没有声明这样的函数——我只是想写它的类型——因为这是result_of预期的。这真的还是病态吗?

4

1 回答 1

10

您正在传递一个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的有趣讨论)。

于 2016-03-07T16:04:54.270 回答