简体   繁体   English

检测嵌套类型的常量

[英]Detecting const-ness of nested type

Normally, if I need to detect whether a type is const I just use boost::is_const . 通常,如果我需要检测类型是否为const我只需使用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: 考虑以下traits模板,它专门用于const类型:

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. 问题是boost::is_const似乎没有检测到traits<const T>::reference是一个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;

This outputs: false false 这输出: false false

Why doesn't it output false true ? 为什么输出false true

Because the reference is not const, it's the type it's referencing that is const. 因为引用不是const,所以它引用的类型是const。 Right, there are no const references. 没错,没有const引用。 So imagine that the reference is a pointer, then the difference is easier to understand: int const* not const, int *const is const. 所以假设引用是一个指针,那么差异就更容易理解: int const* not const, int *const是const。

Use remove_reference to get the actual const type: 使用remove_reference来获取实际的const类型:

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

Because references are not const . 因为引用不是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). 你有一个ref-to-const(考虑一个粗略的模拟, int const* ,其中pointee int有一个const上下文,但指针本身没有)。 The standard mixes terminology here, but I avoid the term "const ref" which is highly misleading. 标准混合了这里的术语,但我避免使用“const ref”这个词,这是一个很容易引起误解的词。

References are inherently immutable as they can only be initialised and then not re-bound, but that does not make them const . 引用本质上是不可变的,因为它们只能初始化然后不能重新绑定,但这并不能使它们成为const

You can remove the reference from the type with boost::remove_reference (as indicated in other answers). 您可以使用boost::remove_reference从类型中删除引用(如其他答案中所示)。

Well, have you noted that is_const<int const&>::value is likewise false? 那你有没有注意到is_const<int const&>::value同样是假的? 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. 当您实例化时,您将获得错误输出中的任何T,大多数实现。

Try this to solve your current problem: 试试这个来解决你当前的问题:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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