Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to conditionally enable a non-const/const data member of a template class based on the constness of the template argument?

Is it possible to conditionally enable a non-const/const data member of a template class based on the constness of the template argument? Or maybe have some conditional typedef? I thought about using std::enable_if with std::is_const, but there is no std::is_not_const that I could use.

class A;

template <typename T>
class Test
{
    A& m_a; // If T != const.
    const A& m_a; // If T == const.
};

Note that always T != A.

like image 308
NFRCR Avatar asked Apr 08 '14 19:04

NFRCR


2 Answers

Yes, you can use std::conditional:

template <typename T>
class Test
{
    typename
    std::conditional<std::is_const<T>::value, const A&, A&>::type
    m_a;
};
like image 117
jrok Avatar answered Nov 18 '22 21:11

jrok


Yes, you can do this. The <type_traits> header has tools for this purpose.

template <typename T>
class Test
{
    typename std::conditional<
        std::is_const<T>::value,
        typename std::add_const<A>::type,
        typename std::remove_const<A>::type
    >::type m_a;
};
  • std::is_const
  • std::add_const / std::remove_const
  • std::conditional

You could even make a helper for this purpose:

//T is type to modify
//S is source type to mimic
struct mimic_const<T, S>
{
public:
    typedef typename std::conditional<
        std::is_const<S>::value,
        typename std::add_const<T>::type,
        typename std::remove_const<T>::type
    >::type type;
};

Then use it like this:

template <typename T>
class Test
{
    typename mimic_const<A, T>::type m_a;
};
like image 39
Timothy Shields Avatar answered Nov 18 '22 20:11

Timothy Shields