C++11:完美转发中的恒常性

c++11: constness in perfect forwarding

本文关键字:常性 转发 完美 C++11      更新时间:2023-10-16

我创建了函数来检测参数的恒定性和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 类型(例如 const int&)上,is_const也总是返回 false。 我尝试添加另一个重载来捕获恒定性

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

然后编译器抱怨检测在应用于const int&时是不明确的。 所以我认为编译器已经正确地计算出 T=const int&,但为什么is_const不返回 true?

std::is_const<T>只检测顶级const。喜欢foo const,或者foo* 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)一样称为.