检测嵌套类型的常量

时间:2011-01-13 18:38:18

标签: c++ templates const traits

通常,如果我需要检测类型是否为const,我只使用boost::is_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>::referenceconst类型。

例如:

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

3 个答案:

答案 0 :(得分: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';

答案 1 :(得分:6)

因为引用不是const。 :)

你有一个ref-to-const(考虑一个粗略的模拟,int const*,其中指针int有一个const上下文,但指针本身没有)。标准混合了这里的术语,但我避免使用“const ref”这个词,这是一个很容易引起误解的内容。

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

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

答案 2 :(得分:4)

那么,您是否注意到is_const<int const&>::value同样是假的?它是。这样的事情应该是你尝试调试这样的模板的第一件事。您可以使用的另一件事是打印机:

template < typename T > struct print;

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

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

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