2013-03-17 42 views
11

考虑这个函数模板:扣除类型后,函数模板中的替换顺序是否有保证?

template<typename T> 
typename soft_error<T>::type foo(T, typename hard_error<T>::type) 
{ } 

从调用foo()的第一个参数的类型推断类型T后,编译器会进行替代T和实例函数签名。

如果首先执行替换返回类型,导致简单替换失败,则编译器将在计算重载集合并搜索其他可行超载(SFINAE)时放弃此函数模板。另一方面,如果第一个函数参数的替换先发生,导致硬错误(例如,由于非直接上下文中的替换失败),则整个编译将失败。

问题:对函数参数和返回类型进行替换的顺序是否有保证?


注:This example似乎表明,在所有主要的编译器(VC11是单独测试,并给了相同的结果)取代的返回类型替代参数类型之前发生。

+0

请注意,[迟到指定返回类型会改变事物](http://liveworkspace.org/code/4cvdpz%2464)。 – 2013-03-17 15:29:19

+0

@NicolBolas:对,这是因为替代实际上是要按照词汇顺序发生 - 顺便说一句Xeo正确地指出,这不是现行标准规定的行为,所以我更正了我的答案 – 2013-03-17 15:33:09

回答

14

[注:此原本并不意味着是一个自我回答的问题,但我偶然发现了解决方案,同时各具特色的问题]


有没有任何保证的为函数参数和返回类型执行替换的顺序?

不符合当前标准。

然而,this Defect Report(礼貌Xeo)表明,这确实是打算如此。下面是段落的C++ 11标准的14.8.2/7所提出的新的措辞(这已成为n3485 draft的一部分):

在所有类型和表达被在函数中使用时的取代键入并在模板 参数声明中。这些表达式不仅包含常量表达式,如 数组边界或非类型模板参数中出现的常量表达式,还包含sizeof,decltype和允许非常量表达式的其他上下文中的常规表达式(即非常量表达式) 。 替换按词汇顺序进行 ,并在遇到导致扣除失败的条件时停止。 [...]

作为正确地评价的问题指出的Nicol Bolas词汇顺序意味着一个后返回类型将后的参数类型被取代,如图this live example

+1

这真的很好。感谢分享这个。 +1来问答。 – Nawaz 2013-03-17 17:54:54