以下无法编译 clang35 -std=c++11
:
#include <iostream>
#include <string>
#include <initializer_list>
class A
{
public:
A(int, bool) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
A(int, double) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
A(std::initializer_list<int>) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
int main()
{
A a1 = {1, 1.0};
return 0;
}
有错误
init.cpp:15:14: error: type 'double' cannot be narrowed to 'int' in initializer list [-Wc++11-narrowing]
A a1 = {1, 1.0};
^~~
init.cpp:15:14: note: insert an explicit cast to silence this issue
A a1 = {1, 1.0};
^~~
static_cast<int>( )
OTOH,它警告缩小和编译 g++48 -std=c++11
init.cpp: In function ‘int main()’:
init.cpp:15:17: warning: narrowing conversion of ‘1.0e+0’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
A a1 = {1, 1.0};
^
init.cpp:15:17: warning: narrowing conversion of ‘1.0e+0’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
并产生结果
A::A(std::initializer_list<int>)
这两种行为都有意义吗?引自 cppreference
将std :: initializer_list作为唯一参数的所有构造函数, 或者作为第一个参数,如果其余参数有默认值 通过对a的重载决策来检查和匹配值 std :: initializer_list类型的单个参数
如果前一个阶段没有产生匹配,则T的所有构造函数 参与对这组参数的重载决策 由带有限制的braced-init-list元素组成 只允许非缩小转换。如果这个阶段 生成一个显式构造函数作为a的最佳匹配 copy-list-initialization,编译失败(注意,简单 复制初始化,根本不考虑显式构造函数)
由于不允许缩小转换,我希望重载决策步骤不匹配 A(std::initializer_list<int>)
构造函数,而不是匹配 A(int, double)
一。例如,改变 A(std::initializer_list<int>)
至 A(std::initializer_list<std::string>)
用两者编译 clang35
和 g++48
和打印
A::A(int, double)
正如所料。