2017-12-28 7 views
3

コンテナ実装の移動コンストラクタnoexceptプロパティが定義されていますか?私はちょうど次のことがない++ GCCまたはMSVCで打ち鳴らすに動作しますが、ということが分かった:異なるコンパイラのstdコンテナの異なるnoexceptプロパティ

std::vector<std::vector<std::unique_ptr<int>>> vector_a; 
std::vector<std::stack<std::unique_ptr<int>>> vector_b; 
vector_a.reserve(10); // this works in all tested compilers 
vector_b.reserve(10); // this only works in clang 

私の質問があり、目的に(これは、標準の不完全な実装によって引き起こされている場合か、それは単純に定義されていない場合?)。

私は、標準コンテナの数をテストした:

#include <iostream> 
#include <deque> 
#include <vector> 
#include <queue> 
#include <stack> 

int main() { 
    std::cout << "Deque: " << std::is_nothrow_move_constructible<std::deque<float>>::value << std::endl; 
    std::cout << "Vector: " << std::is_nothrow_move_constructible<std::vector<float>>::value << std::endl; 
    std::cout << "Queue: " << std::is_nothrow_move_constructible<std::queue<float>>::value << std::endl; 
    std::cout << "Stack: " << std::is_nothrow_move_constructible<std::stack<float>>::value << std::endl; 
} 

のgcc 7.2.1:

Deque: 0 
Vector: 1 
Queue: 0 
Stack: 0 

打ち鳴らす5.0.0:

Deque: 1 
Vector: 1 
Queue: 1 
Stack: 1 

のMicrosoft C/C++バージョン19.00をx64の.23506:

Deque: 0 
Vector: 1 
Queue: 0 
Stack: 0 
std::cout << "Vector Stack: " << std::is_nothrow_move_constructible<std::stack<float, std::vector<float>>>::value << std::endl; 
std::cout << "Vector Queue: " << std::is_nothrow_move_constructible<std::queue<float, std::vector<float>>>::value << std::endl; 

のgcc 7.2.1:

Vector Stack: 1 
Vector Queue: 1 

打ち鳴らす5.0.0:

Vector Stack: 1 
Vector Queue: 1 
基盤となるコンテナなどのベクターを使用してキューとスタックのためのの

EDIT

結果 x64のためののMicrosoft C/C++バージョン19.00.23506:

Vector Stack: 1 
Vector Queue: 1 

答えて

2

stackqueueはコンテナではありません。彼らはコンテナアダプターです。それらはをテンプレート引数として与えるコンテナタイプを使用します。既定では、std::dequeが使用されます。

このように、適応しているコンテナのnoexcept動作を転送します。したがって、 dequeが動くと dequeを使用する stackも同様に動きます。 実際には、コンテナアダプタは、コンポーネントコンテナのnoexcept動作をに転送しません。あるいは少なくとも、彼らは標準によって要求されていません。

実際の容器のnoexcept状態に関しては、vectorにはnoexceptの移動が必要です(これはC++ 17の変更であり、これまでの要件はありませんでした)。残りは実装依存です。

2

vectorの移動コンストラクタは、noexceptが保証され、C++からのみ開始されます。

deque,stackおよびqueue移動コンストラクタはnoexceptではありません。 LLVMの実装がnoexceptであるという事実は、標準と矛盾しない素晴らしい追加です。

deque::swap()を調べると、同様の機能があり、noexcept(C++ 17以降)です。

関連する問題