Search code examples
c++c++11constantsstandardstype-traits

Why does `std::is_const_v` not behave as expected?


#include <iostream>
#include <type_traits>

using namespace std;

template<typename T>
void f(T&&)
{
    cout << boolalpha << std::is_const_v<T> << endl;
    cout << boolalpha << std::is_const_v<T&&> << endl;
}

int main()
{
    const int n = 1;
    f(n);
}

The output is:

false
false

Here, n is an obvious const variable, why does std::is_const_v not behave as expected?


Solution

  • std::is_const is false when the type is a reference:

    cppreference:

    If T is a reference type then is_const<T>::value is always false. The proper way to check a potentially-reference type for const-ness is to remove the reference: is_const<typename remove_reference<T>::type>

    In your specific case, T is a forwarding reference, which will be deduced as lvalue reference when passing a lvalue argument. That's why you see the false in two cases.