【发布时间】:2021-11-05 04:48:44
【问题描述】:
我遇到了我认为很奇怪的事情:
#include <vector>
int numqueues = 1;
std::vector<float> priorities{numqueues, 1.f };
//^^^ warning: narrowing conversion of numqueues from int to float
//std::vector<float> priorities(numqueues, 1.f );
//^^^ No warning or error. And it's not because it's parsed as a function declaration
// as I can call push_back in main.
int main()
{
priorities.push_back(1);// No narrowing conversion needed
}
我已经用几个编译器试过了,这不会编译。
编辑:据说 initializer_list 优先,看起来确实如此,但我试图模仿 std::vector 并且在此示例中我没有得到缩小转换错误:
#include <vector>
#include <iostream>
#include <initializer_list>
template <typename T>
class MyVector
{public:
MyVector(size_t s, float f) {
std::cout << "Called constructor\n";
}
MyVector(std::initializer_list<T> init)
{
std::cout << "Called initializer list constructor\n";
}
};
int main()
{
MyVector<float> foo{ size_t(3), 2.f };
}
我做了同样的事情,用 size_t 和 float 初始化它,就像在另一个例子中一样,这个编译得很好。
【问题讨论】:
-
您在测试中使用了一个常量来表示大小,而不是变量。这是您的诊断信息wandbox.org/permlink/ECXJE0UmSeOl1Zk5
-
@StoryTeller-UnslanderMonica 规则对此有何规定?常量不需要缩小转换?
-
当它是一个常量表达式时,编译器能够知道转换中是否存在重大损失。所以它不必只对类型发出警报。
-
@StoryTeller-UnslanderMonica 那么,如果我真的想调用 (size_t, float) 的构造函数并且因为最麻烦的解析而不能调用,会发生什么?好吧,从这个意义上说,它可能会被误认为是函数声明,这一点并不含糊,但我见过一些情况,当我认为它不可能是函数声明时,它被推断为函数声明。
-
最麻烦的解析总是可以避免的,只要多加一些括号就可以了。丑陋,但可以避免。
标签: c++ class constructor initializer-list type-narrowing