开发者

Detecting const-ness of nested type

开发者 https://www.devze.com 2023-02-03 22:04 出处:网络
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 templat

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

0

精彩评论

暂无评论...
验证码 换一张
取 消