3

I made these type traits to determine if the type is a dynamic container, but recently ran into confusion when a reference to a vector didn't return true.

template<typename T>
struct is_dynamic_container
{
    static const bool value = false;
};

template<typename T , typename Alloc>
struct is_dynamic_container<std::vector<T , Alloc>>
{
    static const bool value = true;
};

I think I need to use std::decay, but I'm having trouble figuring out if it can be done like this rather than at the call site.

template<typename T , typename Alloc>
struct is_dynamic_container<std::decay<std::vector<T , Alloc>>::type>
{
    static const bool value = true;
};

^^This doesn't work.

I just want to be able to write is_dynamic_container<std::vector<int>&> and not is_dynamic_container<std::decay<std::vector<int>&>::type>. Is that possible?

Jonathan
  • 752
  • 1
  • 9
  • 19

2 Answers2

5
template<class T>
using is_dynamic_container_with_decay = is_dynamic_container<std::decay_t<T>>;
T.C.
  • 133,968
  • 17
  • 288
  • 421
3

You could try this:

template<typename T,typename=void>
struct is_dynamic_container
{
    static const bool value = false;
};

template<typename T>
struct is_dynamic_container<T,
  typename std::enable_if<
    !std::is_same<T,typename std::decay<T>::type>::value,
  >::type
>
    : is_dynamic_container<typename std::decay<T>::type>
{};

If you don't mind an intermediate step, there is a simpler and more conservative solution. Rename is_dynamic_container to is_dynamic_container_impl and then

template<typename T>
using is_dynamic_container =
  is_dynamic_container_impl<typename std::decay<T>::type>;

Choose whatever is appropriate in your case.

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180