【问题标题】:SFINAE for true_type and false_type in std::conditionalstd::conditional 中 true_type 和 false_type 的 SFINAE
【发布时间】:2021-10-24 02:30:12
【问题描述】:

编译的最佳方法是什么?

// 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 typetraits


    【解决方案1】:
    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>());
      

      (See a Demo)


      或使用模板特征的部分特化(假设您将只传递指针或非指针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;
      

      (See a Demo)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-16
        • 1970-01-01
        相关资源
        最近更新 更多