C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Make std::span convertible to a const'd span

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Sun, 22 Sep 2024 14:11:09 -0400
On Sun, Sep 22, 2024 at 12:45 PM Jonathan Wakely via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> On Sun, 22 Sept 2024 at 17:21, Oliver Schädlich via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> Maybe the opposite direction as explicit would make also sense.
>>
> I would prefer if that doesn't work.
>

Me too. Two things occur to me:

(1) We permit this:
    using P = T*;
    const T *p;
    T *q = P(p);
but that's only because a functional-style cast *on primitive types* can be
interpreted as a const_cast or reinterpret_cast.
On class types, a functional-style cast is really intended to be like a
static_cast; and you can't do static_cast<P>(p).

(2) We reserve explicit constructors for conversions that are physically
meaningful but "dangerous" in some way, e.g.
    shared_ptr<T>(T*) — "dangerous" in taking ownership of something
previously unowned
    string(string_view) — "dangerous" in doing heap-allocation of something
previously heap-avoidant
    span<int,3>(span<int,2>) — "dangerous" in messing with the span's
number of elements
The last of these is already "taken" by span's explicit constructor. So if
we added
    span<int,3>(span<const int,3>) — "dangerous" in removing
const-qualification from the elements
then we'd have two different dimensions of "danger," both expressed by
explicit conversion. Suppose I'm doing
    auto sp = span<int,3>(otherspan);
That's an explicit conversion, so I'm opting in to "danger"; but did I
think I was opting into the buffer-overflow kind of danger, or the
modifying-a-const-object kind of danger?

If you really wanted to do this (and again, I *don't* think the actual STL
should do this) you might do it by introducing named "cast" functions, like
std::reinterpret_pointer_cast, std::const_pointer_cast, etc., but for spans:
    span<const int, 2> otherspan;
    auto sp = length_span_cast<const int, 3>(otherspan); // cast to a
different length
    auto sp = const_span_cast<int, 2>(otherspan); // cast away const
    auto sp = reinterpret_span_cast<const unsigned char, 8>(otherspan); //
cast to a different type entirely

–Arthur

Received on 2024-09-22 18:11:23