2011-01-13 65 views
7

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

回答

13

因为引用不是const,所以它的引用类型是const。没错,没有const引用。所以想象一下这个引用是一个指针,那么差别就更容易理解了:int const*不是const,int *const是const。

使用remove_reference获得实际的常量类型:

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

唔,你已经注意到,is_const<int const&>::value同样是假的?它是。像这样的东西应该是你为了调试这样的模板而尝试的第一件事情。你可以利用的另一件事是一个类型的打印机:

template < typename T > struct print;

当你实例,你会得到什么T是在错误输出,大多数的实现。

尝试使用此方法解决当前的问题:

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

+1

s/is_cost/is_const / – 2011-01-13 19:05:42

6

因为引用不const。 :)

你有一个ref-to-const(考虑一个粗略的模拟,int const*,其中指针int有一个const上下文,但指针本身不)。标准在这里混合了术语,但是我避免了“const ref”这个高度误导的术语。

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

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