template with bool parameter
You have at least three ways to do it.
i. Use std::conditional:
template <bool isList>
struct A
{
typename std::conditional<isList,
std::list<int>,
std::vector<int>>::type container;
};
ii. Use template specialization for the bool
parameter
template <bool isList>
struct A;
template<>
struct A<true>
{
std::list<int> container;
};
template<>
struct A<false>
{
std::vector<int> container;
};
then
A<true> a1; // container of a1 is a list
A<false> a2; // container of a2 is a vector
iii. Use template functions
If you need a template function type, then you can do it like below. It returns a container based on the entry parameter.
template <bool isList>
auto func() -> typename std::conditional<isList,
std::list<int>,
std::vector<int>>::type
{
typename std::result_of<decltype(func<isList>)&()>::type result;
// ...
return result;
};
then
auto f1 = func<true>(); // f1 is a list
auto f2 = func<false>(); // f2 is a vector
With c++17 onward, there are some cleaner options.
Classes/structs
For classes, the only thing I'd suggest you do differently from masoud's answer with std::conditional
is to use a using
declaration instead of directly using the type when declaring the member variable. That way, the type can be re-used and the typename
is redundant. Also, std::conditional_t
is shorter.
Example:
template<bool isList, typename T>
struct TemplatedStruct
{
using Container = std::conditional_t<isList, std::list<T>, std::vector<T>>;
Container container;
};
Functions
- Use a templated function with the
if constexpr
syntax together withauto
return type deduction. Example:
template<bool isList, typename T>
auto createContainer()
{
if constexpr (isList)
{
return std::list<T>{};
}
else
{
return std::vector<T>{};
}
}
- Use
std::conditional
like in masoud's answer, but cleaner. Either:
template<
bool isList, typename T,
typename Container = std::conditional_t<isList, std::list<T>, std::vector<T>>
>
auto createContainer() -> Container
{
Container result;
// Do stuff that works with both containers I guess
return result;
}
Or:
template<bool isList, typename T>
auto createContainer()
{
using Container = std::conditional_t<isList, std::list<T>, std::vector<T>>;
Container result;
// Do stuff that works with both containers I guess
return result;
}
I removed
#include <list>
#include <vector>
from my examples for simplicity.