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

Con*_*tor 4 c++ explicit sfinae type-traits c++17

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

我可以写is_explicitly_constructible一个的组合std::is_constructiblestd::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
        >
{
};
Run Code Online (Sandbox Code Playgroud)

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

Bar*_*rry 5

是的,这是正确的.类型T可以从参数Aif 明确构造

  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_constructiblepair是如何有条件地实现构造函数的explicit.例如,在libstdc ++中,这两个构造函数optional存在:

隐含的:

 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)
Run Code Online (Sandbox Code Playgroud)

明确的:

  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);
Run Code Online (Sandbox Code Playgroud)

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

  • @Constructor我猜你要找的是 `is_explicitly_convertible&lt;From,To&gt;` 是 `std::is_constructible&lt;To,From&gt;` 和 `is_implicitly_convertible&lt;From,To&gt;` 是 `std::is_convertible&lt;From,到&gt;`。 (2认同)