c++ - 类型推导后函数模板中的替换顺序是否有任何保证?

标签 c++ templates c++11 overloading sfinae

考虑这个函数模板:

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

从调用 foo() 的第一个参数的类型推导出类型 T 后,编译器将继续替换 T并实例化函数签名。

如果首先执行返回类型的替换,导致简单替换失败,编译器将在计算重载集并搜索其他可行重载 (SFINAE) 时丢弃此函数模板。

另一方面,如果对第二个函数参数的替换首先发生,导致硬错误(例如,由于在非立即上下文中的替换失败),整个编译将失败。

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


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

最佳答案

[注意:这本来不是一个 self 回答的问题,但我在设计问题时碰巧找到了解决方案]


Is there any guarantee on the order in which substitution will be performed for the function parameters and return types?

不在当前标准中。

然而,this Defect Report (由 Xeo 提供)表明情况确实如此。以下是 C++11 标准第 14.8.2/7 段的拟议新措辞(已成为 n3485 draft 的一部分):

The substitution occurs in all types and expressions that are used in the function type and in template parameter declarations. The expressions include not only constant expressions such as those that appear in array bounds or as nontype template arguments but also general expressions (i.e., non-constant expressions) inside sizeof, decltype, and other contexts that allow non-constant expressions. The substitution proceeds in lexical order and stops when a condition that causes deduction to fail is encountered. [...]

正如 Nicol Bolas 正确指出的那样在对该问题的评论中,词法顺序 表示尾随返回类型将被替换为参数类型之后,如this live example 中所示。 .

关于c++ - 类型推导后函数模板中的替换顺序是否有任何保证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15462336/

相关文章:

c++ - 推断拥有成员函数的类的类型

在 C++ 应用程序后面运行的 C++ 计时器

c++ - 如何更改共享库的搜索顺序?

c++ - Googletest expect_call 不记录调用

templates - 如何在以下商店结构中添加路径

使用 SFINAE 的 C++ 好友模板

c++ - 将静态成员函数作为参数传递

c++ - 如何从 <chrono> 获取持续时间,如整数毫秒和浮点秒?

c++ - 为什么不使用强制转换语法调用 "operator void"?

c++ - 有没有办法结合编译器防火墙(Pimpl)和默认可复制性的好处?