Reputation: 2019
When writing a custom iterator type, I decided I want to be able to convert from const iterators to non-const iterators. I wrote the following remove_const
function. For some reason the compiler is failing to deduce that const P
is the same as const int*
. The error I get from GCC 8.2 is types 'const P' and 'const int*' have incompatible cv-qualifiers
.
Is there something in my code which is preventing the compiler from deducing correctly? Also, if there is a better way of doing what I want I would love to know.
template <int, typename P>
struct my_iterator { P ptr; };
using iterator = my_iterator<3, int*>;
using const_iterator = my_iterator<3, const int*>;
template <int I, typename P>
my_iterator<I, P> remove_const(my_iterator<I, const P> it) {
return my_iterator<I, P>{ const_cast<P>(it.ptr) };
}
int main() {
const_iterator it{ nullptr };
remove_const( it );
return 0;
}
Here is a godbolt link with the code
Upvotes: 1
Views: 240
Reputation: 172924
For const P
, const
is qualified on P
directly, given P
is int *
, const P
will be int * const
(i.e. const
pointer), not const int *
(pointer to const
).
You can change the code to
template <int I, typename PtoC>
auto remove_const(my_iterator<I, PtoC> it) {
using PtoNC = std::add_pointer_t<std::remove_const_t<std::remove_pointer_t<PtoC>>>;
return my_iterator<I, PtoNC> { const_cast<PtoNC>(it.ptr) };
}
Upvotes: 5