20

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

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

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

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

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

4

2 回答 2

16

但是返回语句格式不正确,SFINAE 会导致结果吗?

提案-n3638说,

SFINAE

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

希望这就是你要找的。

于 2013-07-12T06:41:38.617 回答
4

跟进 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;,则程序格式错误。

于 2013-07-12T13:43:25.000 回答