【发布时间】:2015-02-07 12:24:19
【问题描述】:
下面使用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 作为唯一参数的构造函数, 或者如果其余参数具有默认值,则作为第一个参数 值,被检查,并通过重载决议与 std::initializer_list 类型的单个参数
如果前一个阶段没有产生匹配,T的所有构造函数 参与针对一组参数的重载决议 由支撑初始化列表的元素组成,具有限制 只允许非缩小转换。如果这个阶段 生成一个显式构造函数作为 a 的最佳匹配 复制列表初始化,编译失败(注意,简单 复制初始化,完全不考虑显式构造函数)
由于不允许缩小转换,我希望重载解决步骤与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)
正如预期的那样。
【问题讨论】:
-
大概你的意思是 Clang 3.5。你命名的二进制文件并没有真正的帮助:)
mv clang25 clang35"oops" -
你是对的 :) 这是团队在工作中维护构建系统时使用的版本控制约定,我从未考虑过。
标签: c++ c++11 overload-resolution list-initialization