使用 std::string::assign 来自 boost::array 与 std::array 的不兼容性

Incompatibility using std::string::assign from boost::array Vs std::array

一些遗留代码如下所示:

#include <boost/array.hpp>

boost::array<wchar_t, 1000> data;

void func(std::wstring &str)
{
 str.assign(data.begin());
}

当我们更新到 C++17 时,我正在更新代码以使用 std 等效于 boost,并且我认为 array 是直接替代品,但是当我尝试这个时我得到一个编译错误:

#include <array>

std::array<wchar_t, 1000> data;

void func(std::wstring &str)
{
 str.assign(data.begin());
}

error C2664: 'std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>> &std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>::assign(std::initializer_list<_Elem>)': cannot convert argument 1 from 'std::_Array_iterator<_Ty,2001>' to 'std::initializer_list<_Elem>' with [ _Elem=wchar_t ] and [ _Ty=wchar_t ] and [ _Elem=wchar_t ]

我们在代码库中的很多地方都使用了这种模式,是否有简单的修复方法? boost::arraystd::array 之间的具体区别是什么导致了这种情况,这是否意味着它不能被视为直接替代品?

(我没有写这段代码。我不知道为什么我们不只是使用 wchar_t[];也许作者只是喜欢 boost 中的 'new' 功能。)

boost::array<wchar_t, N>::iterator 定义为 wchar_t *

std::array<wchar_t, N>::iterator 不需要是 wchar_t *.

这就是您的代码无法编译的原因。它假定迭代器是指针。

除此之外,您的代码有问题,因为 str.assign(_pointer_) 假定指针指向一个以 null 结尾的字符串。

不过,好消息是 str.assign(data.begin(), data.end())boost::arraystd::array 都适用。

但是,如果您在数组中间有一个 NUL,那么您将获得与以前不同的行为。这会给你和以前一样的行为:

str.assign(data.begin(), std::find(data.begin(), data.end(), wchar_t(0)))

[稍后:好吧,除了 data 不包含 NUL 的情况。在那种情况下,您之前有未定义的行为,但现在您获得了数组中的所有元素(并且只有那些元素)。 ]