-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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).
STL/stl/inc/xpolymorphic_allocator.h
Lines 261 to 270 in 73924c1
| 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.
Lines 227 to 239 in 73924c1
| 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.