【问题标题】:Can I write a function type that returns a function?我可以编写一个返回函数的函数类型吗?
【发布时间】:2016-03-07 15:48:47
【问题描述】:

以下内容在 gcc 和 clang 上都无法编译

#include <type_traits>

int foo();

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

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

【问题讨论】:

  • 我认为这个“两个编译器上的错误都处理了声明函数返回函数的非法性。”将有用地替换为实际错误
  • 你为什么不直接使用decltype(foo())
  • 你不能形成一个函数类型,该函数返回另一个函数类型。 “函数不应有类型数组或函数的返回类型”dcl.fct/8
  • 将语句更改为 using R = std::result_of_t&lt;decltype(foo)&amp;()&gt;; 可以根据需要进行操作。

标签: c++ language-lawyer c++14 result-of


【解决方案1】:

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

【讨论】:

  • 我真的很喜欢这个 eel.is 东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-13
  • 1970-01-01
相关资源
最近更新 更多