gpt4 book ai didi

c++ - 替换在模板参数推导中如何工作?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:36:57 26 4
gpt4 key购买 nike

C++ 标准 14.8.2$7 说:

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. [ Note: The equivalent substitution in exception specifications is done only when the exception-specification is instantiated, at which point a program is ill-formed if the substitution results in an invalid type or expression. — end note ]

标准在这里提供了一个例子:

template <class T> struct A { using X = typename T::X; };
template <class T> typename T::X f(typename A<T>::X);
template <class T> void f(...) { }
template <class T> auto g(typename A<T>::X) -> typename T::X;
template <class T> void g(...) { }

void h() {
f<int>(0); // OK, substituting return type causes deduction to fail
g<int>(0); // error, substituting parameter type instantiates A<int>
}

为什么调用 g<int>(0)这里有错误吗?不是尾随返回类型 T::X导致替换失败?模板函数有什么区别fg

最佳答案

重点是,首先,

The substitution proceeds in lexical order and stops when a condition that causes deduction to fail is encountered

其次,A<int> 的实例化的定义触发硬错误,而不是替换失败,因为这会导致实例化格式错误的构造 typename T::X (与 T == int )在直接上下文之外。 [temp.deduct]/8 :

Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure. [ Note: The evaluation of the substituted types and expressions can result in side effects such as the instantiation of class template specializations and/or function template specializations, the generation of implicitly-defined functions, etc. Such side effects are not in the “immediate context” and can result in the program being ill-formed. — end note ]

使用有问题的模板,代入 typename T::X在函数类型中导致推导失败(即 SFINAE);代入 typename A<T>::X导致硬错误。由于替换按词汇顺序进行,对于 template <class T> typename T::X f(typename A<T>::X);它代入 typename T::X首先,导致演绎失败,并且不再尝试进一步替换。对于 template <class T> auto g(typename A<T>::X) -> typename T::X; ,另一方面,它代入typename A<T>::X首先,这会导致硬错误。

关于c++ - 替换在模板参数推导中如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38966207/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com