Reputation: 1380
I was writing a test for my iterator types and wanted to check that the reference returned by de-referencing iterators provided by begin()
and cbegin()
are non-const and const respectively.
I tried doing something similar to the following : -
#include <type_traits>
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec{0};
std::cout << std::is_const<decltype(*vec.begin())>::value << std::endl;
std::cout << std::is_const<decltype(*vec.cbegin())>::value << std::endl;
}
But this prints 0
for both cases.
Is there a way to check if a reference is const?
I can use C++11/14/17 features.
Upvotes: 7
Views: 1397
Reputation: 131626
*it
will be a reference rather than the referenced type (int&
or const int&
rather than int
or const int
in your case). So, you need to remove the reference:
#include <iostream>
#include <type_traits>
#include <vector>
int main() {
std::vector<int> vec{0};
std::cout << std::is_const<std::remove_reference<decltype(*vec.begin())>::type>::value << std::endl;
std::cout << std::is_const<std::remove_reference<decltype(*vec.cbegin())>::type>::value << std::endl;
}
This produces:
0
1
Note: The above works uses C++11. @eerorika's answer is more terse, but requires C++17.
Upvotes: 5
Reputation: 5926
You can check the notes on document here: https://en.cppreference.com/w/cpp/types/is_const
If T is a reference type then is_const::value is always false. The proper way to check a potentially-reference type for const-ness is to remove the reference: is_const::type>.
for(auto it=vec.begin(); it!=vec.end(); ++it) {
std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
}
for(auto it=vec.cbegin(); it!=vec.cend(); ++it) {
std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
}
Upvotes: 2
Reputation: 26076
is_const
always returns false
for references. Instead, do:
std::is_const_v<std::remove_reference_t<decltype(*v.begin() )>> // false
std::is_const_v<std::remove_reference_t<decltype(*v.cbegin())>> // true
Upvotes: 3
Reputation: 238351
Remove the reference to get the referenced type to inspect its constness. A reference itself is never const - even though references to const may colloquially be called const references:
std::is_const_v<std::remove_reference_t<decltype(*it)>>
Upvotes: 7