C 11引入了统一初始化,其具有禁止隐式缩小转换的期望特征.例如,int i {2.2}应该是一个错误.
不幸的是,出于向后兼容性的原因,C 03,GCC自4.7以来只给出了这些警告.
GCC的documentation表明此扩展不适用于SFINAE环境,但似乎是错误的:
#include <type_traits> #include <utility> template <typename From,typename To> class is_list_convertible_helper { template <typename To2> static void requires_conversion(To2 t); template <typename From2,typename To2,typename = decltype(requires_conversion<To2>({std::declval<From2>()}))> // ^ Braced initializer static std::true_type helper(int); template <typename From2,typename To2> static std::false_type helper(...); public: using type = decltype(helper<From,To>(0)); }; template <typename From,typename To> class is_list_convertible : public is_list_convertible_helper<From,To>::type { }; static_assert(!is_list_convertible<double,int>::value,"double -> int is narrowing!");
GCC 4.9.1给出了这个输出
$g++ -std=c++11 foo.cpp foo.cpp: In substitution of ‘template<class From2,class To2,class> static std::true_type is_list_convertible_helper<From,To>::helper(int) [with From2 = double; To2 = int; <template-parameter-1-3> = <missing>]’: foo.cpp:18:31: required from ‘class is_list_convertible_helper<double,int>’ foo.cpp:22:7: required from ‘class is_list_convertible<double,int>’ foo.cpp:26:48: required from here foo.cpp:10:46: warning: narrowing conversion of ‘std::declval<double>()’ from ‘double’ to ‘int’ inside { } [-Wnarrowing] typename = decltype(requires_conversion<To2>({std::declval<From2>()}))> ^ foo.cpp:26:1: error: static assertion Failed: double -> int is narrowing! static_assert(!is_list_convertible<double,^
如果没有为每个缩小转换添加特化,有没有办法让这个工作?