使用来自 boost::array 与 std::array 的 std::string::assign 不兼容
Posted
技术标签:
【中文标题】使用来自 boost::array 与 std::array 的 std::string::assign 不兼容【英文标题】:Incompatibility using std::string::assign from boost::array Vs std::array 【发布时间】:2021-08-12 14:59:41 【问题描述】:一些遗留代码如下所示:
#include <boost/array.hpp>
boost::array<wchar_t, 1000> data;
void func(std::wstring &str)
str.assign(data.begin());
当我们更新到 C++17 时,我正在更新代码以使用 boost
等效的 boost
,我认为 array
是直接替代品,但是当我尝试这个时,我得到一个编译错误:
#include <array>
std::array<wchar_t, 1000> data;
void func(std::wstring &str)
str.assign(data.begin());
错误 C2664: 'std::basic_string
,std::allocator > &std::basic_string ,std::allocator >::assign(std::initializer_list<_elem>)': 无法将参数 1 从 'std::_Array_iterator<_ty>' 转换为 'std::initializer_list<_elem>' 和 [ _Elem=wchar_t ] 和 [ _Ty=wchar_t ] 和 [ _Elem=wchar_t ]
我们在代码库中的很多地方都使用了这种模式,有什么简单的解决方法吗? boost::array
和 std::array
之间的具体区别是什么导致了这种情况,这是否意味着它不能被视为直接替代品?
(这段代码不是我写的。我不知道为什么我们不只是使用wchar_t[]
;也许作者只是喜欢boost中的“新”功能。)
【问题讨论】:
str.assign(data.begin(), data.end())
有效吗?否则,如果您确定 data
将被空终止,您可能只需要像 str.assign(data.data())
这样的数组/指针,而不是传递一个迭代器
boost::array::begin
很可能返回一个指针。这是迭代器的有效实现。坦率地说,作者似乎在滥用实现细节。
@CoryKramer 编译确保它工作可能需要更长的时间;)这看起来确实好多了,我想知道 boost 的迭代器有何不同?
【参考方案1】:
boost::array<wchar_t, N>::iterator
被定义为wchar_t *
std::array<wchar_t, N>::iterator
不需要是wchar_t *
。
这就是您的代码无法编译的原因。它假定迭代器是指针。
除此之外,您的代码存在问题,因为str.assign(_pointer_)
假定指针指向一个以空字符结尾的字符串。
不过,好消息是str.assign(data.begin(), data.end())
将适用于boost::array
和std::array
。
但是,如果您在数组中间有一个 NUL,那么您将获得与以前不同的行为。这将为您提供与以前相同的行为:
str.assign(data.begin(), std::find(data.begin(), data.end(), wchar_t(0)))
[稍后:嗯,除了data
不包含 NUL 的情况。在这种情况下,您之前有未定义的行为,但现在您获得了数组中的所有元素(并且只有那些元素)。 ]
【讨论】:
这种用法似乎纯粹是一个字符缓冲区来接收来自 ODBC 调用的结果,传统上你会看到WCHAR[MAX_LEN]
所以我得到的印象是有人在 10 多年前读过关于 boost 数组的内容,并且想使用它们。以上是关于使用来自 boost::array 与 std::array 的 std::string::assign 不兼容的主要内容,如果未能解决你的问题,请参考以下文章
有没有简单的方法来动态增加 boost::multi_array 维度?