I created function to detect the constness and l(r)valueness of the argument.
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";
}
for some reason, is_const always returns false even on const types, for example const int&. I tried adding another overload to capture the constness
template<class T> std::string
detect(const typename std::remove_reference<T>::type& ) { return "const lvalue"; }
compiler then complains that detect is ambiguous when applied to const int&. So I think the compiler has correct figure out T=const int&, but why doesn't is_const return true?
std::is_const<T> only detects top-level const. Like foo const, or foo* const. It doesn't care about "inner" consts, like foo const* or foo const&.
If what you want is to see if type a reference to const, you need to take out the reference first, so the const becomes top-level:
std::is_const<typename std::remove_reference<T>::type>::value
In any case, the functions shown do not allow type deduction, meaning you have to pass T explicitly, like detect<foo const&>(x). Maybe you want something like the following?
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");
}
Which can be called like detect(x).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With