[英]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.这导致了P2499 ( string_view
range constructor should be explicit
),它暗示了标题所说的内容,以及P2516 ( string_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.