c++ - How can I write a type trait to check if a type is convertible to another by a non-narrowing conversion? -
c++ - How can I write a type trait to check if a type is convertible to another by a non-narrowing conversion? -
c++11 introduced uniform initialization, comes desirable feature of forbidding implicit narrowing conversions. example, int i{2.2}
should error.
unfortunately, backwards-compatibility reasons c++03, gcc since 4.7 gives warning these.
gcc's documentation suggests extension doesn't apply in sfinae contexts, appears wrong:
#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 narrowing!");
gcc 4.9.1 gives output
class="lang-none prettyprint-override">$ 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 ‘class is_list_convertible_helper<double, int>’ foo.cpp:22:7: required ‘class is_list_convertible<double, int>’ foo.cpp:26:48: required here foo.cpp:10:46: warning: narrowing conversion of ‘std::declval<double>()’ ‘double’ ‘int’ within { } [-wnarrowing] typename = decltype(requires_conversion<to2>({std::declval<from2>()}))> ^ foo.cpp:26:1: error: static assertion failed: double -> int narrowing! static_assert(!is_list_convertible<double, int>::value, ^
short of adding specializations every narrowing conversion, there way create work?
quite simply, bug in gcc. bug has existed since -std=c++11
has been supported (though worked in gcc 4.6 -std=c++0x
). has been fixed upcoming gcc 5 release, won't backported gcc 4.9.
c++ c++11 gcc sfinae typetraits
Comments
Post a Comment