Nesting Constant Detection

Usually, if I need to determine if there is a const type, I just use boost::is_const . However, I ran into difficulties when trying to detect the constness of a nested type. Consider the following pattern template, which is specialized for const types:

 template <class T> struct traits { typedef T& reference; }; template <class T> struct traits<const T> { typedef T const& reference; }; 

The problem is that boost::is_const does not detect that traits<const T>::reference is of type const .

For example:

 std::cout << std::boolalpha; std::cout << boost::is_const<traits<int>::reference>::value << " "; std::cout << boost::is_const<traits<const int>::reference>::value << std::endl; 

Output: false false

Why doesn't it print false true ?

+7
source share
3 answers

Since the reference is not const, it is the type that it refers to const. That's right, there are no references to const. So, imagine that the link is a pointer, then the difference is easier to understand: int const* not const, int *const is const.

Use remove_reference to get the actual type of const:

 cout << boost::is_const< boost::remove_reference<int const&>::type>::value << '\n'; 
+13
source

Because links are not const . :)

You have a ref-const constant (consider a rough analogue of int const* , where pointee int has a const context, but the pointer itself does not work). The standard mix of terminology is here, but I avoid the term "const ref", which is very misleading.

Links are intrinsically immutable since they can be initialized and then not rearranged, but that does not make them const .

You can remove a link from a type using boost::remove_reference (as indicated in other answers).

+6
source

Well, did you notice that is_const<int const&>::value also false? It. Something like this should be among the first things you are trying to debug patterns like this. Another thing you can use is a generic printer:

template < typename T > struct print;

When you instantiate, you will get that T is in error output, with most implementations.

Try to solve this problem:

is_const< remove_reference< traits<int const>::reference >::type >::value

+4
source

All Articles