如何检查类型 explicitly/implicitly 是否可构造?

How to check if type is explicitly/implicitly constructible?

如何检查某些类型是否可从其他类型显式(或反之亦然)构造?在这种情况下是否有任何 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
        >
{
};

但是我是否考虑了此类代码中所有可能的情况?

是的,这是正确的。如果

,类型 T 可以从参数 A 显式构造
  1. 它完全可以从 A 构造。也就是说,一个假设的T x(a)是有效的。
  2. 隐式转换格式错误。也就是说,假设函数 T test() { return a; } 是病式的。

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++ 使用与您相同的表达式。