2012-04-26 63 views
3

我创建了检测参数的常量和l(r)值的函数。C++ 11:完美转发的常量

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"; 
} 

出于某种原因,is_const始终返回false即使在const的类型,例如const int的&。我尝试添加另一个过载捕捉到常量性

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

然后编译器抱怨其检测当施加到const int的&是不明确的。所以我认为编译器有正确的数字T = const int &,但为什么is_const不会返回true?

+1

你怎么称呼'detect'?参数中的'T'是在非推导的上下文中,所以看起来你必须明确地指定它,例如, '检测(某物)'。哪种失败的目的。 – 2012-04-26 18:07:49

+0

检测由转发功能调用。 – 2012-04-26 19:05:56

回答

9

std::is_const<T>只检测顶层const。像foo constfoo* const。它不关心“内部”const s,如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)