【问题标题】:SFINAE and decltype(auto)SFINAE 和 decltype(自动)
【发布时间】:2013-07-10 15:00:57
【问题描述】:

如果函数模板返回decltype(auto)(或使用auto 的其他类型说明符)但返回语句格式不正确,SFINAE 会产生结果吗? return 语句是否被认为是函数签名的直接上下文?

N3690 草案中似乎没有任何要求。默认情况下,我猜 SFINAE 不适用。

这似乎很不幸,因为您可以编写一个函数来转发到另一个函数,但是您不能像以手写方式编写时那样使其存在以委托为条件。此外,如果没有decltype(auto),就无法检查对等非静态成员函数的存在,因为this 不能在函数签名中使用。然而,这表明存在一个基本问题,因为decltype(auto) 提供了一条路径,可以在成员签名中将类类型视为完整,而事实并非如此。

有没有写过提案,或者有没有在任何地方正式分析过问题?

在成员签名中将类类型视为完整的能力可能具有其他含义……但这只是另一个问题的素材。

【问题讨论】:

  • 我一直想知道这一点。可悲的是,我也懒得遵循 1y 的建议......
  • @MarkGarcia 是的,这是给定的。我只是在问题的末尾添加了一条注释;非模板成员仍有可能打开通往暮光区的虫洞。
  • 如果问题中有一些例子,对于像我这样的笨蛋来说会更容易理解。 :)
  • 一个小例子会让问题更清楚。也许还有其他方法可以实现您想要的。
  • @n.m.总是有更多的方法。我没有被卡住,但我试图避免 8 次重复过载。我正在寻找的答案是指向提案文件的指针,因此我可以判断是否要自己写报告。

标签: c++ auto decltype c++14


【解决方案1】:

但是 return 语句格式不正确,SFINAE 会产生结果吗?

proposal-n3638 说,

SFINAE

由于返回类型是通过实例化模板推导出来的,如果实例化格式不正确,则会导致错误而不是替换失败。这允许自动函数返回一个 lambda,而使用 decltype(returned expression) 模式是不可能的。

希望这就是你要找的。​​p>

【讨论】:

  • 宾果游戏!正是我想要的。我现在需要去,但我稍后会阅读以了解他们如何协调成员实例化与不完整类型。
【解决方案2】:

跟进 Nawaz 的链接,其余问题由 N3690 §7.1.6.4/11 回答:

如果需要使用具有未推导占位符类型的实体类型来确定表达式的类型,则程序格式错误。

这意味着即使 SFINAE 使用返回类型推导,它也不能用于从另一个函数声明中查询一个函数声明。在处理return 语句之前,签名本质上是无效的,该语句出现在class {} 定义的右大括号处,并且在处理了前面成员的定义之后。

从某种意义上说,所有成员 decltype(auto) 函数相对于同一类中的前面函数都是不完整的:

struct s {
    void f() { a(); } // error: use of ‘auto s::a()’ before deduction of ‘auto’
    auto a() { return 3; }
};

这是 GCC 的投诉;如果成员声明被颠倒,它就会消失。这是因为当到达类定义中的} 时,函数定义是按声明顺序处理的。如果语句a();return 3; 之前处理,那么程序是非良构的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 2017-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    相关资源
    最近更新 更多