greatwolf greatwolf - 4 years ago 101
C++ Question

Why is std::is_const::value 'false' even though T's value_type is const?

#include <type_traits>

struct foo;
int main()
{
const foo *bar;

static_assert(std::is_const<decltype(*bar)>::value,
"expected const but this is non-const!");
}


This results in a failing
static_assert
which is unexpected. This is somewhat similar to this question on const references but not quite the same.

In my case, dereferencing
bar
should give an instance of
const foo
as its type but yet
std::is_const
is saying otherwise.

Answer Source

Shortly that's because a reference or a pointer to a const type is not a const type (note that decltype(*bar) isn't const foo, it's const foo &).


Consider the example here:

std::cout << std::is_const<const int*>::value << '\n'; // false
std::cout << std::is_const<int* const>::value << '\n'; // true

That's because in const int * the type is pointer to something const, that is not a const type as intended by is_const (and the standard actually). In int * const the const qualifier applies to the pointer type and not to the pointed one, thus the type is a const one, no matter to what it points.
Something similar applies for const foo &.

Try using this instead:

static_assert(std::is_const<std::remove_pointer_t<decltype(bar)>>::value, "expected const but this is non-const!");

Or this:

static_assert(std::is_const<std::remove_reference_t<decltype(*bar)>>::value, "expected const but this is non-const!");

By removing the pointer/reference with remove_pointer_t/remove_reference_t your type becomes const foo, that is actually a const type.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download