简体   繁体   中英

Detecting const-ness of nested type

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM