如何检查类型 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
显式构造
- 它完全可以从
A
构造。也就是说,一个假设的T x(a)
是有效的。
- 隐式转换格式错误。也就是说,假设函数
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
的这两个构造函数存在:
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)
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++ 使用与您相同的表达式。
如何检查某些类型是否可从其他类型显式(或反之亦然)构造?在这种情况下是否有任何 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
显式构造
- 它完全可以从
A
构造。也就是说,一个假设的T x(a)
是有效的。 - 隐式转换格式错误。也就是说,假设函数
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
的这两个构造函数存在:
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)
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++ 使用与您相同的表达式。