std::conditional 中 true_type 和 false_type 的 SFINAE

问题描述 投票:0回答:2

编译此文件的最佳方法是什么?

// 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 方式工作?

c++ c++11 templates sfinae type-traits
2个回答
3
投票
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;

我们将“执行”推迟到条件满足之后。


2
投票

如果传递的类型(即

Dims
)和
mapped_type
始终是默认可构造的,您可以在中执行以下操作:

#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;

查看演示

© www.soinside.com 2019 - 2024. All rights reserved.