mkm*_*afa 8 c++ type-deduction c++17
template <typename T>
struct X
{
template <typename Iter>
X(Iter a, Iter b) {}
template <typename Iter>
auto f(Iter a, Iter b)
{
return X(a, b);
}
};
Run Code Online (Sandbox Code Playgroud)
在"C++模板,完整指南"第2版中,有前面的示例关于带有注入类名的隐式演绎指南的字幕.作者提到,对于注入的类名禁用了类参数推导,因为f的返回类型将X<Iter>归因于隐式推导指南.但我相信模板构造函数的隐式演绎指南更像是下面的那个.
template <typename T, typename Iter>
X(Iter a, Iter b) -> X<T>;
Run Code Online (Sandbox Code Playgroud)
我的问题是如何将类模板参数类型,即使在这种情况下,可以推断T,并Iter有两种不同类型和参数类型的唯一依靠Iter.即使T可以某种方式推断出来,T并且Iter是独立的,所以Iter从论证中推断出来并不意味着它的X类型是X<Iter>正确的吗?这是书中的文字有些错误,还是演绎指南看起来与我的想法不同?
你是对的.隐式生成的演绎指南确实看起来像你写的那个.模板参数推论永远不会T从中推断出来.这确实不会造成问题.问题在于用户提供的扣除指南.像这样:
template <typename Iter>
X(Iter a, Iter b) -> X<typename Iter::value_type>;
Run Code Online (Sandbox Code Playgroud)
通常添加哪些允许从迭代器中扣除类模板参数.如果注入的类名没有抑制参数推断,那可能会造成严重破坏.作者可能忽略了添加该演绎指南以证明问题的必要性.
以下是问题的说明:
auto v = std::vector<int>{1, 2};
auto x1 = X<float>(begin(v), end(v));
auto x2 = x1.f(begin(v), begin(v));
Run Code Online (Sandbox Code Playgroud)
这是什么类型的x2?如果我们读取类模板定义,我们希望它与X<float>C++ 14一样,但是如果没有关闭类模板参数演绎并且我们添加了演绎指南,我们就会得到X<int>!
想象一下现有的代码库,其中类型在转移到C++之后突然移位17.那将是非常糟糕的.