简体   繁体   English

是否在 c++23 中向 std::string 添加了一个接受 std::array 的新构造函数<char, n> ?</char,>

[英]Was a new constructor added to std::string in c++23 that accepts std::array<char, N>?

Recently a bug was discovered in our code where we were accidentally converting a std::array<char, N> to std::string .最近在我们的代码中发现了一个错误,我们不小心将std::array<char, N>转换为std::string The buggy code doesn't compile in c++20 mode but compiles and //mostly// works in c++23 mode except for some edge cases with null termination.有缺陷的代码不会在 c++20 模式下编译,但会在 c++23 模式下编译和//大部分// 工作,但某些极端情况除外,终止符为 null。 I'm using gcc 11.1.我正在使用 gcc 11.1。

#include <iostream>
#include <string>
#include <array>

int main()
{
    std::array<char, 3> x = {'a', 'b', '\0'};
    std::string s(x);
    std::cout << "'" << s << "'" << " has length " << s.size() << std::endl;
    //outputs "'ab' has length 3"
}

I suspect this may be related to P1989R2 - Range constructor for std::basic_string_view but I don't know what to make of it.我怀疑这可能与P1989R2 - Range constructor for std::basic_string_view有关,但我不知道该怎么做。

Is it a bug or just a weird behavior or what?这是一个错误还是只是一种奇怪的行为还是什么?

Yes, it is related to P1989.是的,它与P1989有关。

One of std::string 's constructors is: std::string构造函数之一是:

template< class StringViewLike >
explicit constexpr basic_string( const StringViewLike& t,
                                 const Allocator& alloc = Allocator() );

which is constrained on StringViewLike being convertible to std::string_view .这受限于StringViewLike可转换为std::string_view

P1989 added this constructor to std::string_view : P1989 将此构造函数添加到std::string_view

template <class R> requires /* ... */
constexpr string_view(R&&);

The constraints there require R to be a contiguous_range with appropriate value type and a few other things.那里的约束要求R是一个具有适当值类型和其他一些东西的contiguous_range Importantly, std::array<char, N> meets those requirements, and this constructor is not explicit .重要的是, std::array<char, N>满足这些要求,并且此构造函数不是explicit的。

As a result, you can now construct a std::string from a std::array<char, N> .因此,您现在可以从std::array<char, N>构造一个std::string

This led to P2499 ( string_view range constructor should be explicit ), which suggested what the title says, and P2516 ( string_view is implicitly convertible from what?), which suggested removing the constructor entirely.这导致了P2499string_view range constructor should be explicit ),它暗示了标题所说的内容,以及P2516string_view可以从什么隐式转换?),它建议完全删除构造函数。 In the end, the decision was to make the constructor explicit rather than removing it entirely (or keeping it implicit):最后,决定是使构造函数explicit化而不是完全删除它(或保持隐式):

template< class R >
explicit constexpr basic_string_view( R&& r );

Because the string constructor from StringViewLike is constrained on convertible to (which requires implicit construction), this means std::string is no longer constructible from std::array<char, N> (or std::vector<char> or... ).因为StringViewLike中的string构造函数受限于可转换为(这需要隐式构造),这意味着std::string不再可从std::array<char, N> (或std::vector<char>或.. .)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C++23 中 std::string::contains 的时间复杂度是多少? - What's the time complexity of std::string::contains in C++23? 标准::数组<char, N>到 std::string - std::array<char, N> to std::string 如何在 C++23 中将标准库宏与 std 模块一起使用 - How to use standard library macros with std module in C++23 C++23 多线程应用程序中的 std::start_lifetime_as 和 UB - std::start_lifetime_as and UB in C++23 multithreaded application 为什么 C++23 std::move_only_function 没有推导指南? - Why does C++23 std::move_only_function not have deduction guides? 为什么在 C++23 中弃用 std::aligned_storage 以及使用什么代替? - Why is std::aligned_storage to be deprecated in C++23 and what to use instead? C++23 std::views::zip 给出对抽象基的引用的视图时出错 class - C++23 std::views::zip errors when given a view of references to abstract base class 将std :: vector <char>的一部分转换为std :: array <char,n>,c ++ 11 - Casting a section of a std::vector<char> to std::array<char, n>, c++11 如何初始化std :: array <char, N> 用字符串文字省略尾随&#39;\\ 0&#39; - How to initialize a std::array<char, N> with a string literal omitting the trailing '\0' c ++ 11-使用{}构造函数直接从char *初始化std :: string - c++11 - initialize std::string from char* directly with {} constructor
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM