C++ 如何从sockaddr_in6创建boost::asio::ip::address_v6而不制作额外副本?

C++ 如何从sockaddr_in6创建boost::asio::ip::address_v6而不制作额外副本?,c++,boost,boost-asio,C++,Boost,Boost Asio,问题在于,address\u v6class严格按照bytes\u typeclass接受原始数据: typedef array< unsigned char, 16 > bytes_type; typedef数组bytes\u type; 但是sockaddr\u in6struct没有这个功能,它有C风格的数组,不复制就不能转换成std::array。因此,我必须创建一个std::array,将数据复制到那里,并将该数组传递到地址_v6,该地址将数据从std::array复制

问题在于,
address\u v6
class严格按照
bytes\u type
class接受原始数据:

typedef array< unsigned char, 16 > bytes_type;
typedef数组bytes\u type;
但是
sockaddr\u in6
struct没有这个功能,它有C风格的数组,不复制就不能转换成
std::array
。因此,我必须创建一个
std::array
,将数据复制到那里,并将该数组传递到
地址_v6
,该地址将数据从
std::array
复制到其内部缓冲区

我希望我可以使用或实现一些C风格的数组查看器类,但无论如何我都无法将其传递给构造函数,因为它不是模板函数


是否有某种方法可以创建一个
地址_v6
,而无需额外复制数据?

std::array
拥有内存,无法创建视图并将其传递给std::array。这是没有必要的。在堆栈上分配std::array并进行复制,这不是昂贵的操作,您只需要复制16个字节。

std::array拥有内存,无法创建视图并将其传递给std::array。这是没有必要的。在堆栈上分配std::array并进行复制,这不是一个昂贵的操作,您只需要复制16个字节。

std::array必须是包含原始数组作为其第一个也是唯一非静态数据成员的结构。由于原始数组包含
无符号字符
s,因此它是标准布局类。因此,我无法从标准中找到以下代码无法工作的原因:

auto& bytearray = reinterpret_cast<std::array<unsigned char,16>&>(ipv6socket->sin6_addr.s6_addr); 
auto&bytearray=reinterpret\u cast(ipv6socket->sin6\u addr.s6\u addr);

如果要复制,请将
auto&
替换为普通
auto

std::array
必须是包含原始数组作为其第一个也是唯一非静态数据成员的结构。由于原始数组包含
无符号字符
s,因此它是标准布局类。因此,我无法从标准中找到以下代码无法工作的原因:

auto& bytearray = reinterpret_cast<std::array<unsigned char,16>&>(ipv6socket->sin6_addr.s6_addr); 
auto&bytearray=reinterpret\u cast(ipv6socket->sin6\u addr.s6\u addr);

如果要复制,请将
auto&
替换为普通
auto

为什么只复制16个字节(在许多现代系统中是两个机器字)?@DavisHerring由于我的内存不好,我忘了数组不会在堆上分配内存,因此没有开销。所以,是的,无论如何它很快,但我仍然好奇如何避免额外的复制。为什么你只关心复制16字节(在许多现代系统中是两个机器字)?@DavisHerring由于我的内存不好,我忘记了数组不会在堆上分配内存,因此没有开销。所以,是的,反正速度很快,但我仍然好奇如何避免额外的复制。这正是我想要的!我也试过做类似的演员,但由于缺乏经验,我没能成功,到处都有错误。但是现在它工作了,谢谢!对任何事情使用该引用都是未定义的行为。作为标准布局并不意味着你可以假装一个对象在那里,如果它不在那里。@DavisHerring为什么它是UB?如果我完全了解这个类的内部结构,并且我确信它们与我所使用的数据一致,那么它仍然是UB?@davishering,我同意std::array是非常仔细地指定的,以便与C样式的数组有点兼容(想象一下游戏开发者的暴动,如果他们没有标准化的话)。应该不难找到关于这个问题的权威章节this@Nikita128:[basic.lval]/11提供了规则的精神,但实际上只适用于标量。[expr.static.cast]/13描述了
reinterpret_cast
无法找到合适的对象(不仅仅是类型!),然后最终[expr.ref]/6.2或[expr.call]/2由于缺少具有给定成员(函数)的对象而忽略,从而产生未定义的行为。这正是我想要的!我也试过做类似的演员,但由于缺乏经验,我没能成功,到处都有错误。但是现在它工作了,谢谢!对任何事情使用该引用都是未定义的行为。作为标准布局并不意味着你可以假装一个对象在那里,如果它不在那里。@DavisHerring为什么它是UB?如果我完全了解这个类的内部结构,并且我确信它们与我所使用的数据一致,那么它仍然是UB?@davishering,我同意std::array是非常仔细地指定的,以便与C样式的数组有点兼容(想象一下游戏开发者的暴动,如果他们没有标准化的话)。应该不难找到关于这个问题的权威章节this@Nikita128:[basic.lval]/11提供了规则的精神,但实际上只适用于标量。[expr.static.cast]/13描述了
reinterpret_cast
无法找到合适的对象(不仅仅是类型!),然后最终[expr.ref]/6.2或[expr.call]/2由于缺少具有给定成员(函数)的对象而忽略,从而产生未定义的行为。是的,您刚刚提醒我,std::array在堆上没有内存分配,因此没有开销。但我还是想弄清楚如何避免额外的复制。是的,您刚刚提醒我std::array在堆上没有内存分配,所以没有开销。但我还是想知道如何避免额外的复制。