Reputation: 13
I want to select one of the standard containers with one template parameter at compile time. Something like
template<typename T>
void foo()
{
using Container = std::conditional_t< std::is_same_v<T, int>,
std::vector, // T is int
std::set>; // any other T
Container<T> bar;
}
How to do this properly?
Upvotes: 0
Views: 464
Reputation: 37607
Solution with std::conditional_t
might be OK (and it was fixed in other answer), but IMHO it is better here use something more primitive: simple old fashioned template specialization:
template<typename T>
void foo()
{
using Container = std::set<T>;
Container<T> bar;
someCode(bar);
}
template<>
void foo<int>()
{
using Container = std::vector<T>;
Container<T> bar;
someOtherCode(bar);
}
Upvotes: 3
Reputation: 119847
The simplest way seems to be
using Container = std::conditional_t< std::is_same_v<T, int>,
std::vector<T>, // T is int
std::set<T>>;
Container bar;
std::conditional_t
allows you to select a type. There is no standard conditional template that would allow to select a template. You can write one if you want but this won't be convenient to use.
template <bool t, template <typename...> typename X, template <typename...> typename Y>
struct conditional_template;
template <template <typename...> typename X, template <typename...> typename Y>
struct conditional_template<true, X, Y>
{
template <typename... ts> using type = X<ts...>;
};
template <template <typename...> typename X, template <typename...> typename Y>
struct conditional_template<false, X, Y>
{
template <typename... ts> using type = Y<ts...>;
};
template <typename... ts>
using Container = conditional_template<true, std::list, std::vector>::type<ts...>;
Container<int> x;
It doesn't seem possible to define an analogue of std::conditional_t
convenience alias.
Upvotes: 1
Reputation: 4655
Without knowing exactly what "properly" means in your question, what you probably want is the following:
template<typename T>
void foo()
{
using Container = std::conditional_t<
std::is_same<T, int>::value,
std::vector<T>, // T is int
std::set<T>>; // any other T
Container bar;
}
Your original code did not work, because
std::conditional_t
needs types as 2nd and 3rd parameters, but you spcified class templates instead.std::is_same_v
in C++14, it arrived in C++17. You need to use std::is_same<X,Y>::value
instead.Full code here.
Upvotes: 0