我相信Bjarne Stroutrup的新书TCPL第4版第66页中的示例有一个小错误,因为class Vector_container
没有std::initializer_list
构造函数。错误消息here确认了这一点。
#include <iostream>
class Vector{
double* elem;
int sz;
public:
Vector(int s):elem{new double[s]}, sz{s} { for(int i = 0; i != sz; ++i) elem[i]= 0; }
Vector(std::initializer_list<double> lst): elem{new double[lst.size()]}, sz(lst.size()) { std::copy(lst.begin(), lst.end(), elem); }
~Vector() { delete[] elem; }
double& operator[](int i) { return elem[i]; }
int size() const { return sz; }
};
class Container{
public:
virtual double& operator[](int i) = 0;
virtual int size() const = 0;
virtual ~Container() {}
};
class Vector_container:public Container{
Vector v;
public:
Vector_container(int s): v{s}{}
~Vector_container() {}
double& operator[](int i) { return v[i]; }
int size() const {return v.size(); }
};
void use(Container& c)
{
const int sz = c.size();
for(int i = 0; i != sz; i++) std::cout << c[i] << '\n';
}
int main()
{
Vector_container vc{10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
use(vc);
}
但是v{s}
构造函数的成员初始化列表中为Vector_container(int)
表达式发出的警告让我感到惊讶,因为它说:warning: narrowing conversion of 's' from 'int' to 'double' inside { }
,这似乎不正确,因为在这种情况下没有缩小。
此外,如果您将Vector_container vc{10, ..., 1};
中的main()
更改为Vector_container vc{10};
,则错误消息会按预期消失,但警告会继续显示。尽管如此,编译器选择了std::initializer-list
类的Vector
构造函数,根据标准中的13.3.1.7/1,我认为这是正确的。
因此,我想知道是否有任何方法强制调用Vector(int)
构造函数,而不是Vector
类中的initializer-list ctor 。示例Vector_container vc{10};
。
答案 0 :(得分:4)
你对重载决议是正确的:内部
Vector_container(int s): v{s}{}
初始化v{s}
选择以下构造函数:
Vector(std::initializer_list<double> lst)
根据[over.match.list] / 1。
当std::initializer_list<double>
从{s}
创建s
类型为int
时,int
到double
的转换范围正在缩小}(n3485)[dcl.init.list] / 7
缩小转化是隐式转化
- [...]
- 从整数类型或未范围的枚举类型到浮点类型,除非源是常量表达式,并且转换后的实际值将适合目标类型并且将 转换回原始类型时生成原始值,或
- [...]
请注意,s
此处不再是常量表达式(作为参数)。缩小转换可能不会出现在std::initializer_list
对象的构造中,[dcl.init.list] / 5
如果缩小转换 需要初始化任何元素,程序格式不正确。
所以警告应该是一个错误(或者它是一个扩展名)。
因此,我想知道是否有办法强制调用
Vector(int)
构造函数,而不是Vector
类中的初始化列表ctor。
我不确定我是否理解正确(请参阅对OP的评论),但不使用list-init解决问题:
Vector_container(int s): v(s) {} // initializer-list ctor not viable