Normally, if I need to detect whether a type is const
I just use boost::is_const
. However, I ran into trouble when trying to detect the const-ness of a nested type. Consider the following traits 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
doesn't seem to detect that traits<const T>::reference
is a const
type.
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;
This outputs: false false
Why doesn't it output false true
?
Because the reference is not const, it's the type it's referencing that is const. Right, there are no const references. So imagine that the reference 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 const type:
cout << boost::is_const<
boost::remove_reference<int const&>::type>::value << '\n';
Because references are not const
. :)
You have a ref-to-const (consider a rough analog, int const*
, where the pointee int
has a const
context, but the pointer itself does not). The standard mixes terminology here, but I avoid the term "const ref" which is highly misleading.
References are inherently immutable as they can only be initialised and then not re-bound, but that does not make them const
.
You can remove the reference from the type with boost::remove_reference
(as indicated in other answers).
Well, have you noted that is_const<int const&>::value
is likewise false? It is. Something like this should be among the first things you try in order to debug templates like this. Another thing you can make use of is a type printer:
template < typename T > struct print;
When you instantiate that you'll get whatever T is in the error output, with most implementations.
Try this to solve your current problem:
is_const< remove_reference< traits<int const>::reference >::type >::value
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With