简体   繁体   中英

Choose member type based on template arguments?

If I have a template class:

template<int N>
class C{
    Something _x;
}

I would like to control the type of class member _x depending on the value of N . Say if N was 0 then _x should be type A, else _x should be type B.

Is this possible?

I don't want to just pass the type as a template parameter because it might be possible to violate the rule determining which type to use. For example I could do C<1, A> which is incorrect.

For a scenario where there are only a few possible types, you can use std::conditional .

#include <type_traits>

struct A {};
struct B {};

template<int N>
class M {
public:
    std::conditional_t<N == 0, A, B> _x;
};

Is this possible?

Yes. It's not too difficult either.

template<int N>
class C{
    typename c_member<N>::type _x;
}

where

struct A {};
struct B {};

template <int N> struct c_member
{
   using type = B;
};

template <> struct c_member<0>
{
   using type = A;
};

You can add more specializations of c_member if you want to.

There are many ways to do this. I like doing overloading, asmit permits easy extensibility.

template<int N>using int_t=std::integral_constant<int,N>;
template<class T>struct tag_t{using type=T; constexpr tag_t(){}};
template<class Tag>using type=typename Tag::type;

struct A{}; struct B{};
inline tag_t<A> something(int_t<0>){return {};}
template<int x>
inline tag_t<B> something(int_t<x>){return {};}

now we just:

template<int N>
class M {
public:
  type<decltype(something(int_t<N>{}))> _x;
};

the only advantage is you get the full power of overload resolution to pick the type, and you don't have to mess with template specialization, and you don't have to make one complex conditional to cover many cases.

If you are picking between two types with simple logic this is overkill.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM