[英]This warning in clang and gcc doesn't seem to be correct
I believe the example below in page 66 of Bjarne Stroutrup's new book, TCPL 4th edition, has a minor error, as the class Vector_container
doesn't have an std::initializer_list
constructor. 我相信Bjarne Stroutrup的新书TCPL第4版的第66页下面的例子有一个小错误,因为
class Vector_container
没有std::initializer_list
构造函数。 The error message here confirms this. 这里的错误消息证实了这一点。
#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);
}
But the warning emitted for the expression v{s}
in the member-initializer list for the Vector_container(int)
constructor surprised me, as it says: warning: narrowing conversion of 's' from 'int' to 'double' inside { }
, which doesn't seem to be correct, as there's no narrowing in this case. 但是对于
Vector_container(int)
构造函数的成员初始化列表中的表达式v{s}
发出的警告让我感到惊讶,因为它说: warning: narrowing conversion of 's' from 'int' to 'double' inside { }
,这似乎不正确,因为在这种情况下没有缩小。
Also, if you change the expression Vector_container vc{10, ..., 1};
另外,如果更改表达式
Vector_container vc{10, ..., 1};
in main()
to Vector_container vc{10};
在
main()
到Vector_container vc{10};
the error message disappears, as expected, but the warning continues to show off. 错误消息按预期消失,但警告继续显示。 Nonetheless the
std::initializer-list
constructor for the Vector
class is chosen by the compiler, and I presume this to be correct, according to 13.3.1.7/1 in the Standard. 尽管如此,编译器选择了
Vector
类的std::initializer-list
构造函数,根据标准中的13.3.1.7/1,我认为这是正确的。
Thus, I wonder if there's any way to impose the invoking of the Vector(int)
constructor, instead of the initializer-list ctor in the Vector
class, in this last example with Vector_container vc{10};
因此,我想知道是否有任何方法在
Vector_container vc{10};
最后一个示例中强制调用Vector(int)
构造函数而不是 Vector
类中的initializer-list ctor Vector_container vc{10};
. 。
You're correct about the overload resolution: Inside 你对重载决议是正确的:内部
Vector_container(int s): v{s}{}
the initialization v{s}
selects the following constructor: 初始化
v{s}
选择以下构造函数:
Vector(std::initializer_list<double> lst)
as per [over.match.list]/1. 根据[over.match.list] / 1。
When the std::initializer_list<double>
is created from {s}
, where s
is of type int
, there is a narrowing conversion from int
to double
(n3485) [dcl.init.list]/7 当从
{s}
创建std::initializer_list<double>
,其中s
是int
类型,从int
到double
(n3485)[dcl.init.list] / 7有一个缩小的转换
A narrowing conversion is an implicit conversion
缩小转换是隐式转换
- [...]
[...]
- from an integer type or unscoped enumeration type to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type, or
从整数类型或未范围的枚举类型到浮点类型,除非源是常量表达式,转换后的实际值将适合目标类型,并在转换回原始类型时生成原始值,或者
- [...]
[...]
Note that s
here is not a constant expression any more (being a parameter). 请注意,此处的
s
不再是常量表达式(作为参数)。 Narrowing conversions may not appear in the construction of an std::initializer_list
object, [dcl.init.list]/5 缩小转换可能不会出现在
std::initializer_list
对象的构造中,[dcl.init.list] / 5
If a narrowing conversion is required to initialize any of the elements, the program is ill-formed.
如果需要缩小转换来初始化任何元素,则程序格式不正确。
So that warning should be an error (or it's an extension). 所以警告应该是一个错误(或者它是一个扩展)。
Thus, I wonder if there's any way to impose the invoking of the
Vector(int)
constructor, instead of the initializer-list ctor in theVector
class.因此,我想知道是否有任何方法强制调用
Vector(int)
构造函数,而不是Vector
类中的initializer-list ctor。
I'm not sure if I understood you correctly (see comments to OP), but not using list-init here solves the problem: 我不确定我是否理解正确(请参阅对OP的评论),但不使用list-init解决了这个问题:
Vector_container(int s): v(s) {} // initializer-list ctor not viable
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.