gpt4 book ai didi

c++ - clang 和 gcc 中的这个警告似乎不正确

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:54:04 26 4
gpt4 key购买 nike

我相信 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);
}

但是 Vector_container(int) 构造函数的成员初始化器列表中的表达式 v{s} 发出的警告让我感到惊讶,因为它说:警告:在 {} 中缩小“s”从“int”到“double”的转换,这似乎不正确,因为在这种情况下没有缩小。

此外,如果将 main() 中的表达式 Vector_container vc{10, ..., 1}; 更改为 Vector_container vc{10}; 错误消息如预期的那样消失了,但警告继续显示。尽管如此,Vector 类的 std::initializer-list 构造函数是由编译器选择的,我认为这是正确的,根据 13.3.1.7/1 in the标准。

因此,我想知道是否有任何方法可以强制调用Vector(int) 构造函数,而不是 Vector 中的初始化列表构造函数 类,在最后一个示例中使用 Vector_container vc{10};

最佳答案

关于重载决议你是正确的:里面

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

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
  • [...]

请注意 s这里不再是常量表达式(作为参数)。缩小转换可能不会出现在 std::initializer_list 的构造中对象,[dcl.init.list]/5

If a narrowing conversion is required to initialize any of the elements, the program is ill-formed.

因此该警告应该是一个错误(或者它是一个扩展)。


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.

我不确定我是否理解正确(参见对 OP 的评论),但这里不使用 list-init 可以解决问题:

Vector_container(int s): v(s) {}  // initializer-list ctor not viable

关于c++ - clang 和 gcc 中的这个警告似乎不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21223992/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com