函数参数的C ++类模板推导(P0091R0)

时间:2016-11-22 16:04:51

标签: c++ c++17

在C ++ 17中,我们可以做类似

的事情
std::pair p = {1,3}; // compiler deduces template parameters to pair<int,int>

cppreference的文档中我了解以下内容不起作用:

template<class T1, class T2>
void bar(std::pair<T1,T2>)
{}
void foo()
{
   bar({1,3}); // No deduction of pair template arguments
}

任何人都可以确认并提供一些见解,为什么这不起作用?从技术上讲这应该有效,对吧?有没有讨论过这项工作,还是有点疏忽?

1 个答案:

答案 0 :(得分:11)

参考是正确的。当前采用的类模板的模板参数推导在[dcl.type.class.deduct]中将应用于声明(以及显式类型转换 - 在声明方面定义):

  

如果推断类类型的占位符在简单声明 decl-specifier-seq 中显示为 decl-specifier ,该声明的 init-declarator 应为

形式      

declarator-id attribute-specifier-seq opt initializer

     

占位符由类模板推导(13.3.1.8)的重载决策选择的函数的返回类型替换。如果 init-declarator-list 包含多个 init-declarator ,则该类型为   替换占位符在每个扣除中应相同。 [例如:

template<class T> struct container {
    container(T t) {}
    template<class Iter> container(Iter beg, Iter end);
};

template<class Iter>
container(Iter b, Iter e) -> container<typename std::iterator_traits<Iter>::value_type>;

std::vector<double> v = { /* ... */};
container c(7);                          // OK, deduces int for T
auto d = container(v.begin(), v.end());  // OK, deduces double for T
container e{5, 6};                       // error, int is not an iterator
     

-end example]

提案或通过的关于从 braced-init-list 推断出类模板特化的措辞中没有任何内容。