Skip to content

<scoped_allocator>, <xpolymorphic_allocator.h>: Pre-C++20 overload set of construct might be incorrect #3383

Description

Describe the bug
This program is well-formed in C++17 (but ill-formed since C++20 due to WG21-P0591), because the overload set of construct was specially designed for std::pair (N4659 [mem.poly.allocator.mem], cppreference).

#include <cstddef>
#include <memory_resource>
#include <type_traits>
#include <utility>

int main()
{
    std::pair<int, int> pr{};
    std::pmr::polymorphic_allocator<std::byte> pa{};

    pa.construct<int, int>(&pr);
}

However, MSVC STL always implements the C++20 overload set of construct, and hence rejects this program in C++17 mode (Godbolt link).

template <class _Uty, class... _Types>
void construct(_Uty* const _Ptr, _Types&&... _Args) {
// propagate allocator *this if uses_allocator_v<_Uty, polymorphic_allocator>
#if _HAS_CXX20
_STD uninitialized_construct_using_allocator(_Ptr, *this, _STD forward<_Types>(_Args)...);
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
allocator<char> _Al{};
_Uses_allocator_construct(_Ptr, _Al, *this, _STD forward<_Types>(_Args)...);
#endif // ^^^ !_HAS_CXX20 ^^^
}

scoped_allocator_adaptor::construct has exactly the same issue.

template <class _Ty, class... _Types>
void construct(_Ty* _Ptr, _Types&&... _Args) { // construct with varying allocator styles
#if _HAS_CXX20
_STD apply(
[_Ptr, this](auto&&... _New_args) {
_Scoped_outermost_traits<scoped_allocator_adaptor>::construct(
_Scoped_outermost(*this), _Ptr, _STD forward<decltype(_New_args)>(_New_args)...);
},
_STD uses_allocator_construction_args<_Ty>(inner_allocator(), _STD forward<_Types>(_Args)...));
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
_Uses_allocator_construct(_Ptr, _Scoped_outermost(*this), inner_allocator(), _STD forward<_Types>(_Args)...);
#endif // ^^^ !_HAS_CXX20 ^^^
}

The issue has been present even before implementing WG21-P0591 (#1668). I'm not sure whether this is a bug or an intentional design.

Additional context
LWG-3677 may be related to this if we want consistent behaviors in C++17 & C++20 modes.

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 working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions