C++ Logo

std-proposals

Advanced search

Re: [std-proposals] User defined decay operator

From: Jeremy Rifkin <rifkin.jer_at_[hidden]>
Date: Thu, 20 Mar 2025 16:39:42 -0600
Hi,

This idea would benefit from a lot of elaboration on exactly how this
proposed decay is supposed to happen and when.

> Some consider this "bad feature" but for me this is more is "bad
implementation" of "good feature".

It's broadly considered a bad feature because implicit conversions can be
subtle and surprising. This does not change with implementation.

> I think that many user defined types could benefit from this
functionality.
> Proxy objects

Can you clarify how you think some sort of user-specified decay helps the
proxy object case? That already works fine as-is.

> Expression templates

What you're describing is a bug in the implementation of that expression
template. I'm also not sure how decay is supposed to help that.

> Recent problem discussed on this mailing list with ref types

It's not clear to me how decay is supposed to change that, especially
without breaking code. This is just an unfortunate consequence of the
design of std::minmax.

Cheers,
Jeremy


On Thu, Mar 20, 2025 at 10:16 AM Marcin Jaczewski via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Right now the only type that undergoes decaying is C array (aside of
> refs or bit fields).
> Some consider this "bad feature" but for me this is more is "bad
> implementation" of "good feature".
>
> I think that many user defined types could benefit from this functionality.
>
> Proxy objects:
> ```
> std::vector<bool> ff = { false, false };
> for (auto b : ff)
> {
> b = true;
> }
> assert(ff[0] == true);
> ```
>
> Expression templates:
> ```
> auto matrix = Matrix2x2{1, 2, 3, 4}
> auto mul = matrix * Vector2{3, 4};
> Vector2 v = mul + Vector2{1, 1}; //UB because `mul` is expression and
> dangle temporal vector
> ```
>
> Recent problem discussed on this mailing list with ref types:
>
> ```
> auto [a, b] = std::minmax(foo, 10);
> auto c = a; // UB if `a` refer to `10`
> ```
>
> Another could be a safer version of C array that is not copyable like
> `std::array`
> and instead of decay to pointer, it will decay to `std::span`.
>
> And finally if someone desires to ban "Almost Always Auto" as it could
> be useful for
> very heavy types for unexpected copies in generic code (by setting `=
> delete`).
>
> ```
> auto x = a; //error
> auto& x = a; //ok, no decay
> NestedVector x = a; //ok
> auto x = NestedVector{ a }; //ok
> ```
>
> Code that enable it would look like:
>
> ```
> struct Foo
> {
> Bar operator auto()
> {
> return Bar{};
> }
> };
>
> struct auto_ptr //pre C++11 unique_ptr
> {
> //nothing change but in places where it could be used diagnostic is
> raised
> [[obsolete]] auto_ptr operator auto() = default;
> };
>
> struct MyArray
> {
> //ban decay from temp objects like return from functions.
> std::span<int> operator auto() && = deleted;
> std::span<int> operator auto();
> };
>
> template<typename T1, typename T2>
> struct MyTuple
> {
> T1 t1;
> T2 t2;
> //decay propagate to members, making ref tuple safer to use if
> returned form `std::minmax`
> MyTuple<std::decay_t<T1>, std::decay_t<T2>> operator auto() {
> return { t1, t2 }; }
> };
> ```
>
> When a type has multiple `operator auto` then all versions need to
> return the same type.
> Additionally, the returned type need not have a decay operator (or its
> `=default`).
>
> Overall this make `auto x =` generally more safe to use and more regular.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2025-03-20 22:39:56