true_type 和 false_type 在 std::conditional 中的 SFINAE
SFINAE for true_type and false_type in std::conditional
进行此编译的最佳方法是什么?
// Precondition: Dims is either a pointer or std::map.
using T = std::conditional_t<std::is_pointer_v<Dims>,
std::remove_pointer_t<Dims>,
typename Dims::mapped_type>;
当 Dims
是指针时,我得到:
error: template argument 3 is invalid
当条件为 true
时,如何使其以 SFINAE 方式工作?
如果传递的类型(即 Dims
)和 mapped_type
始终是默认可构造的,您可以在 c++17 中执行如下操作:
#include <map>
#include <type_traits> // std::is_pointer_v
template<typename Type> auto helper()
{
if constexpr (std::is_pointer_v<Type>) return std::remove_pointer_t<Type>{};
else if constexpr (!std::is_pointer_v<Type>) return typename Type::mapped_type {};
}
// helper trait
template<typename Dims>
using ConditionalType_t = decltype(helper<Dims>());
或者使用模板特征的部分特化(假设您将只传递指针或非指针 std::map
类型)
#include <type_traits> // std::is_pointer_v
// traits to see passed type is a std::map
template<typename> struct is_std_map final: std::false_type {};
template<typename Key, typename Value, typename... Rest>
struct is_std_map<std::map<Key, Value, Rest...>> final : std::true_type {};
// the partial specialization of helper traits
template<class T, class Enable = void> struct helper_traits final {};
template<typename T>
struct helper_traits<T, std::enable_if_t<std::is_pointer_v<T>>> final {
using type = std::remove_pointer_t<T>;
};
template<typename T>
struct helper_traits<T, std::enable_if_t<is_std_map<T>::value && !std::is_pointer_v<T>>> final {
using type = typename T::mapped_type;
};
// trait helper
template<typename Type> using ConditionalType_t = typename helper_traits<Type>::type;
template<class T>
struct mapped_type{using type=typename T::mapped_type;};
using T = typename std::conditional_t<std::is_pointer_v<Dims>,
std::remove_pointer<Dims>,
mapped_type<Dims>>::type;
我们将“执行”推迟到条件之后。
进行此编译的最佳方法是什么?
// Precondition: Dims is either a pointer or std::map.
using T = std::conditional_t<std::is_pointer_v<Dims>,
std::remove_pointer_t<Dims>,
typename Dims::mapped_type>;
当 Dims
是指针时,我得到:
error: template argument 3 is invalid
当条件为 true
时,如何使其以 SFINAE 方式工作?
如果传递的类型(即 Dims
)和 mapped_type
始终是默认可构造的,您可以在 c++17 中执行如下操作:
#include <map>
#include <type_traits> // std::is_pointer_v
template<typename Type> auto helper()
{
if constexpr (std::is_pointer_v<Type>) return std::remove_pointer_t<Type>{};
else if constexpr (!std::is_pointer_v<Type>) return typename Type::mapped_type {};
}
// helper trait
template<typename Dims>
using ConditionalType_t = decltype(helper<Dims>());
或者使用模板特征的部分特化(假设您将只传递指针或非指针 std::map
类型)
#include <type_traits> // std::is_pointer_v
// traits to see passed type is a std::map
template<typename> struct is_std_map final: std::false_type {};
template<typename Key, typename Value, typename... Rest>
struct is_std_map<std::map<Key, Value, Rest...>> final : std::true_type {};
// the partial specialization of helper traits
template<class T, class Enable = void> struct helper_traits final {};
template<typename T>
struct helper_traits<T, std::enable_if_t<std::is_pointer_v<T>>> final {
using type = std::remove_pointer_t<T>;
};
template<typename T>
struct helper_traits<T, std::enable_if_t<is_std_map<T>::value && !std::is_pointer_v<T>>> final {
using type = typename T::mapped_type;
};
// trait helper
template<typename Type> using ConditionalType_t = typename helper_traits<Type>::type;
template<class T>
struct mapped_type{using type=typename T::mapped_type;};
using T = typename std::conditional_t<std::is_pointer_v<Dims>,
std::remove_pointer<Dims>,
mapped_type<Dims>>::type;
我们将“执行”推迟到条件之后。