如何检查类型是否显式/隐式可构造?

时间:2017-03-14 12:52:22

标签: c++ sfinae c++17 typetraits explicit

如何检查某些类型是否可以从其他类型显式(或反之,隐式)构造?在这种情况下,是否有任何SFINAE技巧?

我可以将is_explicitly_constructible写为combination of std::is_constructible and std::is_convertible

#include <type_traits>

template <typename Type, typename Argument>
struct is_explicitly_constructible
    : std::bool_constant
        <
            std::is_constructible<Type, Argument>::value &&
            !std::is_convertible<Argument, Type>::value
        >
{
};

但我是否考虑过这些代码中的所有可能情况?

1 个答案:

答案 0 :(得分:5)

是的,这是正确的。类型T可以从参数A显式构造,如果

  1. A可以构建。也就是说,假设T x(a)有效。
  2. 隐含的转换是不正确的。也就是说,假设函数T test() { return a; }将是不正确的。
  3. std::is_constructible测试#1,std::is_convertible测试#2的有效性。因此,想要#1而非#2将是is_explicitly_constructible,而#1和#2将是is_implicitly_constructible

    这样的is_explicitly_constructible / is_implicitly_constructible对就是如何有条件地explicit实现构造函数。例如,在libstdc ++中,存在optional的这两个构造函数:

    implicit

     template <typename _Up = _Tp,
                enable_if_t<__and_<
                  __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
                  is_constructible<_Tp, _Up&&>,   // (*) 
                  is_convertible<_Up&&, _Tp>      // (*)
                  >::value, bool> = true>
      constexpr optional(_Up&& __t)
    

    explicit

      template <typename _Up = _Tp,
                enable_if_t<__and_<
                  __not_<is_same<optional<_Tp>, decay_t<_Up>>>,
                  is_constructible<_Tp, _Up&&>,        // (*)
                  __not_<is_convertible<_Up&&, _Tp>>   // (*)
                  >::value, bool> = false>
      explicit constexpr optional(_Up&& __t);
    

    您可以看到libstdc ++使用与您相同的表达式。