Ron
Ron

Reputation: 2019

Type deduction with const qualifiers failing

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

Answers (1)

songyuanyao
songyuanyao

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

Related Questions