c ++ 11:完美转发中的constness

时间:2012-04-26 17:57:16

标签: c++ c++11

我创建了函数来检测参数的constness和l(r)值。

template<class T> std::string
detect(typename std::remove_reference<T>::type&&) {
    return std::string(std::is_const<T>::value ? "const " : "") + "rvalue";
}
template<class T> std::string
detect(typename std::remove_reference<T>::type&) {
    return std::string(std::is_const<T>::value ? "const " : "") + "lvalue";
}

由于某种原因,即使在const类型上,is_const也总是返回false,例如const int&amp;。我尝试添加另一个重载来捕获constness

template<class T> std::string
detect(const typename std::remove_reference<T>::type& ) { return "const lvalue"; }

编译器然后抱怨当应用于const int&amp;时,检测是不明确的。所以我认为编译器有正确的数字输出T = const int&amp;,但为什么不是is_const返回true?

1 个答案:

答案 0 :(得分:9)

std::is_const<T>仅检测到顶级const。与foo constfoo* const相同。它并不关心“内部”const,例如foo const*foo const&

如果您想要查看是否键入对const的引用,则需要先取出引用,以便const成为顶级:

std::is_const<typename std::remove_reference<T>::type>::value

在任何情况下,显示的函数都不允许类型推导,这意味着您必须明确地传递T,例如detect<foo const&>(x)。也许你想要类似下面的东西?

template<class T> std::string
detect(T&&) { // have T be deduced
    return std::string(std::is_const<typename std::remove_reference<T>::type>::value ? "const " : "")
         + (std::is_lvalue_reference<T>::value? "lvalue" : "rvalue");
}

可以像detect(x)一样调用。