c++11: constness in perfect forwarding

c++, c++11

Solution

`std::is_const<T>` only detects top-level `const`. Like `foo const`, or `foo* const`. It doesn't care about "inner" `const`s, 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)`.

Problem

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?

Original source