如何实现类型特征的连接

Nit*_*pta 3 c++ c++17

template <typename T, typename... Tc>
constexpr bool ConjuctionofConvertible () noexcept
{
    return std::conjunction<std::is_convertible_v<T, Tc>...>::value;
}
Run Code Online (Sandbox Code Playgroud)

出现错误:

template <typename T, typename... Tc>
constexpr bool ConjuctionofConvertible () noexcept
{
    return std::conjunction<std::is_convertible_v<T, Tc>...>::value;
}
Run Code Online (Sandbox Code Playgroud)

Ted*_*gmo 7

您只需要使用is_convertible而不是辅助变量is_convertible_v

template <typename T, typename... Tc>
constexpr bool ConjuctionofConvertible () noexcept
{
    return std::conjunction<std::is_convertible<T, Tc>...>::value;
}
Run Code Online (Sandbox Code Playgroud)

或者

template <typename T, typename... Tc>
constexpr bool ConjuctionofConvertible () noexcept
{
    return std::conjunction_v<std::is_convertible<T, Tc>...>;
}
Run Code Online (Sandbox Code Playgroud)

请参阅以下可能的实现conjunction

template<class...> struct conjunction : std::true_type { };

template<class B1> struct conjunction<B1> : B1 { };

template<class B1, class... Bn>
struct conjunction<B1, Bn...> 
    : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
                              ^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

您会注意到它需要一个类型(带有成员value),而不是bool.


其他有趣的注释,复制和编辑自std::conjuction

std::conjunctionC++17 中添加了折叠表达式conjuction使用折叠表达式 的原因之一conjunction是短路。

Bi如果存在带有 的模板类型参数bool(Bi::value) == false,则实例化conjunction<B1, ..., BN>::value不需要实例化Bj::valuefor j > i

短路实例化conjunction与折叠表达式不同:像折叠表达式一样(... && Bs::value)实例化每个Bin Bs,而std::conjunction_v<Bs...>一旦可以确定值就停止实例化。如果后面的类型实例化成本昂贵或者在使用错误类型实例化时可能导致硬错误,则这特别有用。