为什么不能std :: tuple 可以复制?
建有this online compiler,下面的代码:为什么不能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年
为什么是这样呢?是否有POD类型的std::tuple
的有效理由,更不用说简单的std::pair
,不能简单地复制?我认为他们的实现提供了一些自定义赋值操作符,但它们与编译器生成的默认版本有什么不同?
只要琐碎的可复制性涉及pair
就是标准不要求复制/移动赋值运算符是平凡的。该标准明确声明,复制/移动构造函数是默认的,但对于作业不是这样。一个实现也可以默认它们,但标准并不要求它。
没有真正的理由为什么标准不需要它。但事实并非如此。
对于tuple
,东西是很多更复杂。许多tuple
实现基于具有正确大小/对齐的存储缓冲区,并且使用位置new
来构建该缓冲区内的各个成员。这一切都很好,但这样的类型必须实现手动复制/移动构造函数,因为它必须调用每种类型的复制/移动构造函数。即使它知道它们都是可复制的并通过memcpy
复制它们,但这仍然是一个手动操作。这使它不能享受微不足道的可复制性。
现在,有tuple
的实现,如果类型是可复制的,它们可以是可复制的。但是没有要求以这种方式实现它们。如果所有类型都是可复制的,并且以其他方式以不同的方式实现它们,那么要求它们实现它们自己的一种方式会使得实现变得复杂。
由于std::tuple
具有复制/移动ctor和赋值运算符,因此它使该类不可复制。
一个平凡的可复制类是一类
Has no non-trivial copy constructors (this also requires no virtual functions or virtual bases) Has no non-trivial move constructors Has no non-trivial copy assignment operators Has no non-trivial move assignment operators Has a trivial destructor
但std::tuple
具有以上所有的构造函数和赋值运算符。
没有证明元组的特殊成员函数是非平凡的,答案并不完整。 –
通过定义[std :: tuple](http://en.cppreference.com/w/cpp/utility/tuple)的copy/move ctors/assignments,它已经意味着这样的ctors /操作符不是微不足道的。 – Mine
http://*.com/questions/36625317/error-cannot-pass-objects-of-non-trivially-copyable-type-through意味着该标准不需要它,所以实现不打扰 – happydave