C++ 如何在编译时从不同类型中选择类型?

C++ 如何在编译时从不同类型中选择类型?,c++,c++11,c++14,metaprogramming,C++,C++11,C++14,Metaprogramming,我想这样做: template <uint64_t N> struct a { static constexpr T1 v1 = {}; static constexpr T2 v2 = {}; static constexpr auto v3 = (N % 2 == 1 ? v1 : v2); }; 模板 结构a{ 静态constexpr T1 v1={}; 静态constexpr T2 v2={}; 静态constexpr auto v3=(N%2==1?v1:v2

我想这样做:

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

但是我不能将(?:)用于不同的类型。如何做到这一点?

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

如果您可以使用C++17(但您只标记了C++11和C++14),那么最好使用
If constexpr
基于解决方案(非常优雅,基于Evg的lambda),IMHO

在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)> );
 }
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>{}); 
 };
#包括
模板
结构Foo
{
静态constexpr int v1={};
静态constexpr long v2={};
模板
constexpr static std::如果getV3()
{返回v1;}
模板
constexpr static std::如果getV3()
{返回v2;}
静态constexpr auto v3=getV3();
};
int main()
{
静态断言(std::is_same_v);
静态断言(std::is_same_v);
}
正如Evg所建议的(谢谢!)您可以使用重载(好的旧标记调度)避免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)> );
 }
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>{}); 
 };
模板
结构Foo
{
静态constexpr int v1={};
静态constexpr long v2={};
constexpr静态自动获取v3(std::true\u类型)
{返回v1;}
constexpr静态自动获取v3(std::false\u类型)
{返回v2;}
静态constexpr auto v3=getV3(std::integral_常量{});
};

这是否回答了您的问题?查找模板专业化(或者,美国拼写,专业化)@AlexLarionov,你能添加一些关于使用这个问题的方法的信息吗?非常好的
std::get()
解决方案:在C++11/C++14中也有效。@max66
std::get
解决方案只在C++14的编译时有效。C++11没有将
std::get
定义为
constepr
@humancompiler-D'Oh!你说得对:
constepr
来自C++14。@max66奇怪的是,对于GCC和Clang,它甚至可以与
-std=C++11
一起工作。可能,他们已经在C++11中为这些函数设置了
constexpr
。@Evg-Well。。。从clang我得到一个编译器错误。。。但我从gcc确认。。。。不好的部分是,添加“
-pedantic
”。。。我认为我们应该考虑这是一个GCC错误(在迂回的情况下),而不是sFANE,也可以使用过载解决方案<代码> STD::整合素常数{} /COD>。