为什么不能std :: tuple< int>可复制的吗? [英] Why can't std::tuple<int> be trivially copyable?

查看:86
本文介绍了为什么不能std :: tuple< int>可复制的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

内置此在线编译器,其代码如下:

#include <iostream>
#include <type_traits>
#include <tuple>

int main() {
    std::cout << std::is_trivially_copyable<std::tuple<int>>::value << std::endl;
    std::cout << std::is_trivially_copyable<std::pair<int, int>>::value << std::endl;

    std::cout << std::is_trivial<std::tuple<int>>::value << std::endl;
    std::cout << std::is_trivial<std::pair<int, int>>::value << std::endl;
    return 0;
}

输出:

0
0
0
0

我在Visual Studio 2015中得到相同的结果。

I'm getting the same results with Visual Studio 2015.

为什么会这样?是否有正当理由POD类型的 std :: tuple ,更不用说简单的 std :: pair 了,不可复制吗?我假设它们的实现提供了一些自定义赋值运算符,但是它们与编译器生成的默认版本有何不同?

Why is that the case? Is there a valid reason an std::tuple of POD types, let alone a simple std::pair, couldn't be trivially copyable? I presume their implementations provide some custom assignment operators, but how would they be different from the default versions generated by the compiler?

推荐答案

就琐碎的可复制性而言,使崩溃的原因是该标准并不要求琐碎的复制/移动赋值运算符。该标准明确声明复制/移动构造函数是默认的,但分配不是这样。一个实现也可以默认使用它们,但是标准不需要它。

The thing that trips pair up as far as trivial copyability is concerned is that the standard does not require that the copy/move assignment operators be trivial. The standard explicitly declares that the copy/move constructors are defaulted, but not so for the assignments. An implementation could default them as well, but the standard does not require it.

没有充分的理由解释为什么该标准不需要它。

There's no really good reason why the standard doesn't require it. But it doesn't.

对于元组,事情要很多 。许多 tuple 实现都是基于具有正确大小/对齐方式的存储缓冲区,并使用放置位置 new 来构造该缓冲区中的单个成员。一切都很好,但是这种类型必须实现手动的复制/移动构造函数,因为它必须调用每种类型的复制/移动构造函数。即使它知道它们都是微不足道的副本,并通过 memcpy 复制了它们,这仍然是手动操作。

For tuple, things are a lot more complicated. Many tuple implementations are based on having a storage buffer of the right size/alignment, and using placement new to construct the individual members within that buffer. That's all fine and good, but such a type has to implement a manual copy/move constructor, since it must call the copy/move constructor of each type. Even if it knew that they were all trivially copyable and copied them via memcpy, that's still a manual operation. And that disqualifies it from trivial copyability.

现在,存在 tuple 的实现,如果类型是可复制的。但是并不需要以这种方式实现它们。如果所有类型都是可复制的,这将使 tuple 实现非常复杂,要求它们以一种方式实现自身,否则将以另一种方式实现。

Now, there are implementations of tuple which could be trivially copyable if the types are trivially copyable. But there is no requirement to implement them that way. And it would complicate tuple implementations tremendously to do require them to implement themselves one way if all the types are trivially copyable, and implement them in a different way otherwise.

这篇关于为什么不能std :: tuple&lt; int&gt;可复制的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆