初始化程序列表的模板替换错误

时间:2019-02-22 14:10:43

标签: c++ templates initializer-list

我知道如何使以下代码起作用:我只是取消注释Printer的第二个构造函数。

这个想法很简单:我想编写一个构造函数/函数,该函数可以接受存储在我可以迭代的一些简洁数据结构中的几个参数。我希望它至少可以与向量和列表一起使用(确实可以),但也可以与初始化列表一起使用(而且不可以)。

我使用以下简单语法(可能比我想要的通用一些,我不使用模板模板),因此我不必编写可变参数模板即可处理std的分配器类型::

rbind

但是为什么我应该为初始化列表明确地编写一个特定的构造函数?错误是“无法将'{4,5,6}”从'转换为'打印机'”。

基本上,这说明替换不适用于初始化程序列表。但是为什么呢?

2 个答案:

答案 0 :(得分:2)

用括号括起来的初始化器列表(以前是 braced-init-list )不是std::initializer_list。它可以转换为一个,但不是一个。它也不是容器类型。它根本不是一种类型,实际上,它是由以下符号序列组成的语法构造:

  

{初始值设定项列表, opt }

     

{}

因此,此语法无法完全使用:

Printer pi1 = {4,5,6};      
Printer pi2 ({4,5,6}); //same as above if explicit

如果Printeraggregate,则它可以执行聚合初始化。

否则,您会被迫接受std::initializer_list,而该T{a, b, c, ...}可以由您提供的括号括起来的inititalizer列表构建。


更多信息:

您实际上使用该语法进行的操作称为 list-initialization (聚合初始化是列表初始化的一种)。只是为了进一步混淆,当用于初始化std::initializer_list之类的类型时,它被称为 initializer list 。请勿将其与std::initializer_list混淆。

在C ++ 11中添加std::initializer_list时,它得到了特殊处理。现在,可以使用 braced-init-list 在构造函数中构造临时std::vector<int>。在这里,您看到我们突然能够像创建std::vector<int> vec{1, 2, 3, 4, 5, ...};一样容易地创建std::initializer_list

但是,需要警惕的是go get github.com/kubernetes-incubator/cri-tools/cmd/crictl 构造函数是编译器将选择的{high}构造函数when you least suspect

答案 1 :(得分:0)

替换

Printer pi1 = {4,5,6};      
Printer pi2 ({4,5,6}); //same as above if explicit      

通过类似

Printer pi1 = vector<int>{4,5,6};      
Printer pi2 (vector<int>{4,5,6}); //same as above if explicit