Skip to content

<xutility>: SFINAE constraint on construct_at prevents emplacing immovable objects with copy elision #2620

Description

@Chlorie

Describe the bug
Currently the constraint on construct_at is implemented via SFINAE

STL/stl/inc/xutility

Lines 132 to 134 in f099e9c

template <class _Ty, class... _Types,
class = void_t<decltype(::new (_STD declval<void*>()) _Ty(_STD declval<_Types>()...))>>
constexpr _Ty* construct_at(_Ty* const _Location, _Types&&... _Args) noexcept(

This causes an error when trying to emplace immovable objects with copy elision:
xutility(145): error C2783: '_Ty *std::construct_at(_Ty *const ,_Types &&...) noexcept(<expr>)': could not deduce template argument for '<unnamed-symbol>'

Example code:

struct S
{
    int v;
    S(int v): v(v) {}
    S(const S&) = delete;
};

union U
{
    char c;
    S s;
    U(): c{} {}
    ~U() noexcept {}
};

struct copy_elider
{
    operator S() const { return S(42); }
};

int main()
{
    U u;
    // AFAIK this should work since C++17 mandates copy elision
    std::construct_at(&u.s, copy_elider{});
}

Yet if the constraint is implemented via concepts, i.e.

template <class _Ty, class... _Types>
    requires requires (void* ptr, _Types&&... _Args) { ::new (ptr) _Ty(static_cast<_Types&&>(_Args)...); }
constexpr _Ty* construct_at(_Ty* const _Location, _Types&&... _Args) noexcept(

then the example code above works as expected. I don't know the reason that these two behaviors differ though...

This issue hinders the ability to emplace immovable objects into optionals or variants using the copy elision converter trick shown above.

STL version
VS Community 2022, Version 17.1.2

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcompilerCompiler work involvedfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions