初始化列表中构造函数的模板参数推导

时间:2016-11-19 12:19:25

标签: c++ language-lawyer c++17 template-deduction

Kona会议上,已批准构造函数(P0091R0)的模板参数扣除。它简化了一些变量定义:

std::pair   p  {1,2};     // o.k., constructor pair<int,int>(1,2)
std::vector v1 (10, 0);   // o.k., 10 zeroes, constructor vector<int>(size_t n, T initvalue)
std::vector v2 {10, 0};   // o.k., 2 values: 10, 0, apparently initializer list?
std::vector v3 = {10, 0}; // o.k., same as v2?

但是,以下行不能在gcc 7 HEAD 201611版本(live example)中编译:

std::vector v4 = {3};     // error: no matching function for call to 'std::vector(int)'
std::vector v5 {1, 2, 3}; // error: 'int' is not a class
std::set    s  {1, 2, 3}; // error: no matching function for call to 'std::set(int,int,int)'

这些只是过多的桥梁&#34;,因为它们涉及初始化列表? 它们是否被模板类型参数扣除所覆盖? 当编译器符合C ++ 1z时,它们会被允许吗?

2 个答案:

答案 0 :(得分:4)

您需要一对额外的花括号才能使代码正常工作:

std::vector v4 = {{1, 5}}; 
std::vector v5 {{1, 2, 3}};  
std::set    s  {{1, 2, 3}};

答案 1 :(得分:0)

因为你想调用foo::foo(const initializer_list &)构造函数,你需要告诉编译器有一个 exaclty 一个参数,所以你需要一对额外的括号或大括号:

std::vector v5 ({1, 2, 3});
std::set    s  ({1, 2, 3});
               ^         ^

通过这种方式,编译器知道您只调用一个参数为const initializer_list &的函数,而不是具有三个int s的函数。