I was rather surprised that the following code:
#include <iostream>
#include <type_traits>
using namespace std;
int main(int argc, char* argv[]) {
cout << boolalpha << is_const<const float&>::value << endl;
return 0;
}
Prints false
. Removing the reference works correctly:
#include <iostream>
#include <type_traits>
using namespace std;
int main(int argc, char* argv[]) {
cout << boolalpha << is_const<remove_reference<const float&>::type>::value << endl;
return 0;
}
Printing out true
.
Both were compiled with g++ -std=c++11 test.cpp
, using G++ version:
g++ (Ubuntu 5.3.0-1ubuntu1~14.04) 5.3.0 20151204
Thinking about it, I can understand that there are two types in play here: the reference type and the type that is referenced. The type that is referenced is const
, so the second case makes sense. For the first case, I would expect it to either return if the referenced type is const
or always true
instead, because references AFAIK can't be "reassigned".
Why does it return false
instead?
The outcome is correct.
References are never const
, because they cannot be cv-qualified. You are correct in saying that they cannot be reassigned (and are, as such, immutable in a sense), but that is not the same as being const
-qualified.
If you got true
purely because the referent is const
, then that would be completely inconsistent with the meaning of is_const
in all other cases. Consider, for example, pointers. What should is_const<int const*>::value
be?