Skip to content

<string>, <sstream>: Is the _String_constructor_rvalue_allocator_tag internal constructor necessary? #4929

@frederick-vs-ja

Description

@frederick-vs-ja

When considering the bug reported in LLVM-101960 for MSVC STL, I found that in addition to optional, one internal constructor of basic_string is buggy in a similar way (Godbolt link). The constructor was added by #919 in responding to review comments in #919 (comment).

Example

#include <string>
#include <string_view>

template<class>
constexpr bool is_basic_string_v = false;
template<class C, class T, class A>
constexpr bool is_basic_string_v<std::basic_string<C, T, A>> = true;

template<class>
constexpr bool is_basic_string_view_v = false;
template<class C, class T>
constexpr bool is_basic_string_view_v<std::basic_string_view<C, T>> = true;

struct NastyStringConverter {
    template<class T, std::enable_if_t<!is_basic_string_view_v<T> && !is_basic_string_v<T>, int> = 0>
    operator T() const { return T{}; }
};

int main()
{
    // in C++17 the initializer list ctor is selected
    // in C++20 the internal ctor is selected, which doesn't seem conforming
    std::string(NastyStringConverter{}, std::allocator<char>{}); 
}

STL/stl/inc/xstring

Lines 1148 to 1152 in 91e4255

basic_string(_String_constructor_rvalue_allocator_tag, _Alloc&& _Al)
: _Mypair(_One_then_variadic_args_t{}, _STD move(_Al)) {
// Used exclusively by basic_stringbuf
_Construct_empty();
}

Instead of fixing this constructor, I guess it might be better to remove it. As of LWG-2593, move construction must not change the value of the source allocator, so it's arguable that there shouldn't be observable difference between move and copy construction. But it seems allowed that side effects can be different.


There's a similar thing in list:

STL/stl/inc/list

Lines 807 to 810 in 91e4255

template <class _Any_alloc>
explicit list(_Move_allocator_tag, _Any_alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _STD move(_Al)) {
_Alloc_sentinel_and_proxy();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions