0

I would like to have a template class that wraps a container, but I would like to make a choice of which container to wrap according to the value of the template parameter. Something like:

template<typename T>
class A{
  std::vector<T> MyContainer;
  // ...
}

template<>
class A<bool>{
  std::deque<bool> MyContainer;
  // ...
}

but avoiding all the code duplication that template specialization involves. I was trying to see if std::enable_if could help me to do some trick but I haven't figured any way.

Kae
  • 279
  • 2
  • 10
  • 1
    What about simply providing the container type as another (dependent) template parameter? – πάντα ῥεῖ Nov 02 '14 at 12:28
  • I don't know if your example is real, but you have to know that `std::vector` is already different in the STLibrary. – Caduchon Nov 02 '14 at 12:35
  • 1
    @πάνταῥεῖ That is too ugly. The user of the class shouldn't have to take care of that. That is business of the class, then the class should take care of it. – Kae Nov 02 '14 at 12:35
  • 2
    @Caduchon It is exactly that reason why I want to not use `std::vector` in that case. – Kae Nov 02 '14 at 12:36

2 Answers2

4

Can use std::conditional as Nawaz said :

#include <type_traits>

template <typename T>
using MyContainerType = typename std::conditional<
                        std::is_same<T, bool>::value,
                        std::deque<T>,
                        std::vector<T>
                        >::type ;

template<typename T>
class A{
  //std::vector<T> MyContainer;
  // ...
    MyContainerType<T> C;
} ;
Community
  • 1
  • 1
P0W
  • 46,614
  • 9
  • 72
  • 119
  • 1
    BTW, now you could use just `std::is_same{}` instead of `std::is_same::value`. C++14 is out and fully implemented by GCC and Clang. – Nawaz Nov 02 '14 at 13:41
3

You could do:

typedef typename boost::mpl::if_c<
    std::is_same<T, bool>::value,
    std::deque<T>,
    std::vector<T>
>::type MyContainerType;

See reference.

Or could write your own:

typedef typename ContainerSelector<T>::type MyContainerType;

where:

template <typename T>
struct ContainerSelector {
    typedef std::vector<T> type;
};

template <>
struct ContainerSelector<bool> {
    typedef std::deque<bool> type;
};
Barry
  • 286,269
  • 29
  • 621
  • 977
  • 4
    In C++ Standard Library, you have `std::conditional` which can be used instead of `mpl::if_c`. – Nawaz Nov 02 '14 at 12:37
  • This works for me. Wait for 5 mins. And it is good Nawaz's comment so I don't have to use Boost. – Kae Nov 02 '14 at 12:37
  • @Nawaz wow could NOT remember what the std one was called. Thanks. – Barry Nov 02 '14 at 12:48