如果函数模板返回decltype(auto)
(或使用auto
的另一个类型说明符),但返回语句的格式不正确,是否会导致SFINAE?return
语句是否被视为函数签名的直接上下文?
在N3690草案中似乎没有要求这样做。默认情况下,我猜SFINAE不适用。
这似乎很不幸,因为您可以编写一个函数来转发到另一个函数,但您不能像编写手写函数时那样使它的存在以委托为条件。此外,在没有decltype(auto)
的情况下无法检查对等非静态成员函数的存在,因为this
不能在函数签名中使用。然而,这表明了一个基本问题,因为decltype(auto)
提供了一条路径,可以将成员签名中的类类型视为完整的,而实际上却不是。
建议已经写好了吗,或者问题已经被正式分析过了吗?
在成员签名中将类类型视为complete的能力可能具有其他含义…但这只是另一个问题的素材。
发布于 2013-07-12 14:41:39
但是返回语句将是病态的,
会产生结果吗?
SFINAE
由于返回类型是通过实例化模板推导出来的,如果实例化是错误的,则返回类型为,这将导致错误而不是替换失败。这允许自动函数返回lambda,这在使用decltype(返回的表达式)模式时是不可能的。
希望这就是你要找的。
发布于 2013-07-12 21:43:25
在纳瓦兹的链接之后,剩下的问题由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的抱怨;如果成员声明颠倒,它就会消失。这是因为当到达来自类定义的}
时,函数定义是按声明顺序处理的。如果在return 3;
之前处理语句a();
,那么程序的格式是错误的。
https://stackoverflow.com/questions/17608637
复制相似问题