Reputation: 30615
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.
Upvotes: 3
Views: 2592
Reputation: 275385
There are many ways to do this. I like doing overloading, as it 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()=default;
};
template<class Tag>
using type_t=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_t<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.
Upvotes: 2
Reputation: 206577
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.
Upvotes: 5
Reputation: 29022
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;
};
Upvotes: 8