C++ Logo


Advanced search

Subject: [std-proposals] More general version of const_iterator
From: Marcin Jaczewski (marcinjaczewski86_at_[hidden])
Date: 2020-03-02 15:25:45

In my recent work I stumbled on problem that I need have two types
that have same members but different `const`-nes of them:

class C
    X* a;
    X* b;
    Y* c;

class C_const
    const X* a;
    const X* b;
    const Y* c;

My first thongs was that it should be some language mechanics that
will allow some thing like that e.g. new cv named `const_inner` that
will with some help for user convert type `C` to `C_const`. But after
some thoughts I see this is impossible (constructor and destructor are
not aware of cv, but they have need different implementation to make
it work). Aside from that we would double again number of function to
handle all possible cv combinations.
And this is probably simplest langrage change that could make it
happens, other could only make language more complicated.

But I see that std lib could reduce pain of defining this types and
handing them in generic way.
First we would need p0847r4, this on its own do not fix this problem
but as build block allow to fix this. Then we define new template
template<typename T>
using const_inner_t = ??;
template<typename From, typename T>
using const_inner_as_t = ??;

Idea is this aliases will convert types like `T*`, `T&`,
`std::shared_ptr<T>` to:

static_assert(std::is_same_v<const_inner_t<T*>, const T*>);
static_assert(std::is_same_v<const_inner_t<T&>, const T&>);
std::shared_ptr< constT>>);
static_assert(std::is_same_v<const_inner_t<iterator>, const_iterator>);
//helper alias to switch between versions:
static_assert(std::is_same_v<const_inner_as_t<int, T*>, T*>);
static_assert(std::is_same_v<const_inner_as_t<const int, T*>, const T*>);

This with p0847r4 allow code like:
template<typename Dummy>
struct iterator_impl
    const_inner_as_t<Dummy, std::vector<int>::iterator> i;

    auto operator->() -> const_inner_as_t<Dummy, std::vector<int>::iterator>
        return i;
    //helper using that is used by `const_inner_t` to select correct
type for user defined types
    using const_inner = iterator_impl<const Dummy>;
using iterator = iterator_impl<void>;
using const_iterator = const_inner_t<iterator>;

template<typename Self>
auto foo(this Self f) -> const_inner_as_t<Self, iterator>
    return { f.vec.begin() };

if functionality like this would be common place it would heavy
simplify handling this problems that it would stop need language
solution to fix.

STD-PROPOSALS list run by std-proposals-owner@lists.isocpp.org

Standard Proposals Archives on Google Groups