#include <iostream>
struct X {
X(std::initializer_list<int> list) { std::cout << "list" << std::endl; }
X(float f) { std::cout << "float" << std::endl; }
};
int main() {
int x { 1.0f };
X a(1); // float (implicit conversion)
X b{1}; // list
X c(1.0f); // float
X d{1.0f}; // list (narrowing conversion) ARG!!!
// warning: narrowing conversion of '1.0e+0f' from 'float' to 'int'
// inside { } [-Wnarrowing]
}
Run Code Online (Sandbox Code Playgroud)
有没有其他方法可以std::initializer_list从过载列表中删除(即,使非列表ctors更有利),而不是使用()初始化,或者至少禁止缩小转换(除了将警告变为错误)?
我使用的是使用GCC 4.8的http://coliru.stacked-crooked.com/编译器.
考虑以下代码:
#include <iostream>
int main()
{
int i{10.1}; // narrowing, should not compile
std::cout << i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
根据C++ 11标准,它不应该编译(禁止在大括号初始化中缩小.)
现在,编译g++4.9.2 -std=c++11仅发出警告
warning: narrowing conversion of '1.01e+1' from 'double' to 'int' inside { } [-Wnarrowing]
Run Code Online (Sandbox Code Playgroud)
删除-std=c++11标志会导致关于大括号init的警告,但不会导致任何缩小:
warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
Run Code Online (Sandbox Code Playgroud)
另一方面,如果你编译,g ++ 5 不会编译它g++5 -std=c++11.但是,如果-std=c++11省略,那么即使是g++5愉快地编译它,只给出一个与大括号init相关的警告,而不是缩小:
warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
Run Code Online (Sandbox Code Playgroud)
上面的行为似乎g++4.9有些错误,不应该编译代码,g++5如果你忘记指定,编译它会更奇怪-std=c++11.这是一个已知的问题吗?