2016-08-05 57 views
8

建有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,不能簡單地複製?我認爲他們的實現提供了一些自定義賦值操作符,但它們與編譯器生成的默認版本有什麼不同?

+1

http://stackoverflow.com/questions/36625317/error-cannot-pass-objects-of-non-trivially-copyable-type-through意味着該標準不需要它,所以實現不打擾 – happydave

回答

7

只要瑣碎的可複製性涉及pair就是標準不要求複製/移動賦值運算符是平凡的。該標準明確聲明,複製/移動構造函數是默認的,但對於作業不是這樣。一個實現也可以默認它們,但標準並不要求它。

沒有真正的理由爲什麼標準不需要它。但事實並非如此。

對於tuple,東西是很多更復雜。許多tuple實現基於具有正確大小/對齊的存儲緩衝區,並且使用位置new來構建該緩衝區內的各個成員。這一切都很好,但這樣的類型必須實現手動複製/移動構造函數,因爲它必須調用每種類型的複製/移動構造函數。即使它知道它們都是可複製的並通過memcpy複製它們,但這仍然是一個手動操作。這使它不能享受​​微不足道的可複製性。

現在,有tuple的實現,如果類型是可複製的,它們可以是可複製的。但是沒有要求以這種方式實現它們。如果所有類型都是可複製的,並且以其他方式以不同的方式實現它們,那麼要求它們實現它們自己的一種方式會使得實現變得複雜。

6

由於std::tuple具有複製/移動ctor和賦值運算符,因此它使該類不可複製。

cpp reference

一個平凡的可複製類是一類

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具有以上所有的構造函數和賦值運算符。

+0

沒有證明元組的特殊成員函數是非平凡的,答案並不完整。 –

+1

通過定義[std :: tuple](http://en.cppreference.com/w/cpp/utility/tuple)的copy/move ctors/assignments,它已經意味着這樣的ctors /操作符不是微不足道的。 – Mine

相關問題