通常,如果我需要检测类型是否为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>::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
?
答案 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