On Tue, Jun 17, 2025 at 1:45 AM Ivan Matek via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
I actually had similar problems many years ago when I had vector<unique_ptr<T>> and API was taking const vector<const T*>& , so this trick worked fine :).

This is closely related to the ideas of
- is_trivially_constructible_from<T, U>
- is_trivially_swappable_with<T, U>
- is_trivially_relocatable_from<T, U>

The idea is that since
    using T = std::unique_ptr<int>;
    using U = int*;
    void construct(T *dst, U *src) {
      ::new (dst) T(*src);
    }
can be accomplished by a memcpy, then is_trivially_constructible_from<T, U> can be true.

However, the thing in this thread is yet again different: it's kind of like `is_trivially_const_referenceable_as<T, U>`.
The problem is, I don't see how the compiler could ever infer this kind of thing for user-defined types. It could be achievable for primitive types, e.g. the compiler could tell us that `__is_trivially_const_referenceable_as(int, long)` on appropriate platforms. But that's not useful for programmers. And even with an attribute or something, it doesn't seem ergonomic (or even possible at all, really) for someone to write

    template<class T>
    struct [[trivially_constructible_from(T*)]] unique_ptr {
        explicit unique_ptr(T *p) : p_(p) {}
        T *p_;
    };

because it would be a combinatorial explosion — there are many types, an open-ended set of (possibly user-defined) types, that our unique_ptr might be trivially-constructible-from.

–Arthur