如何在编译时从一些不同的类型中选择类型?

问题描述

我想做这样的事情:

template <uint64_t N>
struct a {
  static constexpr T1 v1 = {};
  static constexpr T2 v2 = {};
  static constexpr auto v3 = (N % 2 == 1 ? v1 : v2);
};

但是我不能将(?:)与其他类型一起使用。我该怎么做?

解决方法

例如,您可以使用if constexpr和lambda函数(C ++ 17):

template <std::uint64_t N>
struct a {
  static constexpr T1 v1 = {};
  static constexpr T2 v2 = {};
  static constexpr auto v3 = 
    [] {
        if constexpr (N % 2 == 1) 
            return v1;
        else
            return v2;
    }();
};

使用std::tuple(C ++ 14)的另一种解决方案:

template <std::uint64_t N>
struct a {
  static constexpr T1 v1 = {};
  static constexpr T2 v2 = {};
  static constexpr auto v3 = std::get<N % 2>(std::make_tuple(v2,v1));
};
,

如果您可以使用C ++ 17(但仅标记了C ++ 11和C ++ 14),则最好使用基于if constexpr(基于Evg的lambda非常优雅)的解决方案,恕我直言。>

在C ++ 17之前,我想您可以尝试使用SFINAE。例如

#include <type_traits>

template <int N>
struct Foo
 {
   static constexpr int v1 = {};
   static constexpr long v2 = {};

   template <int M = N>
   constexpr static std::enable_if_t<M % 2 == 1,int> getV3 ()
    { return v1; }

   template <int M = N>
   constexpr static std::enable_if_t<M % 2 != 1,long> getV3 ()
    { return v2; }


   static constexpr auto v3 = getV3(); 
 };

int main ()
 {
   static_assert( std::is_same_v<int const,decltype(Foo<1>::v3)> );
   static_assert( std::is_same_v<long const,decltype(Foo<2>::v3)> );
 }

如Evg所建议的(谢谢!),您可以避免SFINAE使用重载(旧标签分发)。例如

template <int N>
struct Foo
 {
   static constexpr int v1 = {};
   static constexpr long v2 = {};

   constexpr static auto getV3 (std::true_type)
    { return v1; }

   constexpr static auto getV3 (std::false_type)
    { return v2; }

   static constexpr auto v3 = getV3(std::integral_constant<bool,N%2>{}); 
 };

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...