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

78 Views Asked by At

Some legacy code looks like:

#include <boost/array.hpp>

boost::array<wchar_t, 1000> data;

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

I am updating code to use std equivalents to boost as we update to C++17, and I thought array was a direct replacement, but when I try this I get a compile error:

#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 ]

We use this pattern in quite a lot of places in our codebase, is there a trivial fix? What specifically is the difference between boost::array and std::array which causes this, and does this mean it cannot be considered a drop-in replacement?

(I didn't write this code. And I don't know why we aren't just using wchar_t[]; maybe the author just liked the 'new' features in boost.)

1

There are 1 best solutions below

1
On BEST ANSWER

boost::array<wchar_t, N>::iterator is defined as an wchar_t *

std::array<wchar_t, N>::iterator is not required to be a wchar_t *.

That's why your code fails to compile. It assumes that the iterators are pointers.

Besides that, the code you have is problematic because str.assign(_pointer_) assumes that the pointer points to a null-terminated string.

However, the good news is that str.assign(data.begin(), data.end()) will work for boost::array and std::array both.

However, if you have a NUL in the middle of the array, then you'll get different behavior than you did before. This will give you the same behavior as before:

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

[Later: Well, except in the case where data did not contain a NUL. In that case, you had undefined behavior before, but now you get all the elements in the array (and only those). ]