似乎要测试const-ness,必须测试模板参数,但要测试rvalue-ness,必须测试实际参数。 (这是使用VC ++ 2012.)这段代码说明了我的意思:
#include <type_traits>
#include <string>
#include <iostream>
using namespace std;
template<class T>
void f(T& x) {
cout << "f() is_const<T> and is_const<decltype<x)>" << endl;
cout << is_const<T>::value << endl; // Prints 1 when arg is const
cout << is_const<decltype(x)>::value << endl; // Prints 0 when arg is const
}
template<class T>
void g(T&& x) {
cout << "g() is_const<T> and is_const<decltype<x)>" << endl;
cout << is_const<T>::value << endl; // Prints 0 when arg is const
cout << is_const<decltype(x)>::value << endl; // Prints 0 when arg is cons
cout << "g() is_rvalue_reference<T> and is_rvalue_reverence<decltype(x)>" <<endl;
cout << is_rvalue_reference<T>::value << endl; // Prints 0 when arg is rvlaue
cout << is_rvalue_reference<decltype(x)>::value << endl; // Prints 1 when arg is rvalue
}
int main()
{
const std::string str;
f(str); // const argument
cout << endl;
g(std::string("")); // rvalue argument
return 0;
}
我很难理解为什么会这样。有人可以解释,或指向我解释它的文章?如果需要,我将深入研究C ++ 11标准。有人知道相关部分吗?
答案 0 :(得分:5)
原因是你误解了事情。 x
在任何这些示例中永远不会是const
,因为没有const
引用类型(无论如何都无法更改引用引用的内容)。在is_const<T>
中,您基本上忽略了您将x
声明为T&
。
rvalue ref测试也存在类似的误解。传递左值时,T
中的T&&
(称为通用引用,btw)将推导为U&
,当传递右值时,U
将推导为is_rvalue_reference<T>
。在测试x
时,您再次忽略您将T&&
声明为is_const<T>
。在测试T
时,您没有说明const
将成为参考的事实,如上所述,它永远不会是g
。
std::is_const<typename std::remove_reference<T>::type>::value
的正确测试将是
std::is_rvalue_reference<T&&>::value
和