8

通常,如果我需要检测一个类型是否是const我只需使用boost::is_const. 但是,在尝试检测嵌套类型的 const 时遇到了麻烦。考虑以下特征模板,它专门用于 const 类型:

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

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

问题是boost::is_const似乎没有检测到这traits<const T>::reference是一种const类型。

例如:

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;

这输出:false false

为什么不输出false true

4

3 回答 3

13

因为引用不是 const,所以它引用的类型是 const。对,没有 const 引用。所以假设引用是一个指针,那么区别就更容易理解了:int const*不是const,int *const是const。

使用 remove_reference 获取实际的 const 类型:

cout << boost::is_const<
            boost::remove_reference<int const&>::type>::value << '\n';
于 2011-01-13T18:40:46.193 回答
6

因为引用不是const. :)

你有一个 ref-to-const (考虑一个粗略的类比,int const*,指针intconst上下文,但指针本身没有)。该标准在这里混合了术语,但我避免使用具有高度误导性的术语“const ref”。

引用本质上是不可变的,因为它们只能被初始化,然后不能重新绑定,但这并不能使它们成为const.

您可以从类型中删除引用boost::remove_reference(如其他答案中所示)。

于 2011-01-13T18:58:51.377 回答
4

那么,你有没有注意到这is_const<int const&>::value同样是错误的?这是。为了调试这样的模板,你应该首先尝试这样的事情。您可以使用的另一件事是类型打印机:

template < typename T > struct print;

当您实例化时,您将在大多数实现中得到错误输出中的任何 T 。

试试这个来解决你当前的问题:

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

于 2011-01-13T18:46:55.420 回答