c – 如何通过非缩小转换来编写类型特征以检查类型是否可以转换为另一种类型?

前端之家收集整理的这篇文章主要介绍了c – 如何通过非缩小转换来编写类型特征以检查类型是否可以转换为另一种类型?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
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,^

如果没有为每个缩小转换添加特化,有没有办法让这个工作?

解决方法

很简单,这是海湾合作委员会的 bug.该错误已经存在,因为-std = c 11已被支持(尽管它在GCC 4.6中使用-std = c 0x).它已经为即将发布的GCC 5版本修复,但可能不会被移植到GCC 4.9.

猜你在找的C&C++相关文章