2017-12-28 28 views
3

컨테이너 구현에 대한 이동 생성자 noexcept 속성이 정의되어 있습니까? 난 그냥 다음하지 ++ GCC 또는 MSVC에서 그 소리에서 작동하지만 것을 발견 :다른 컴파일러의 표준 컨테이너에 대한 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 

마이크로 소프트 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 
기반 컨테이너와 같은 벡터를 이용하여 대기열 스택 516,

EDIT

결과 에 대한 6,510,403,210 마이크로 소프트 C/C++ 버전 19.00.23506 :

Vector Stack: 1 
Vector Queue: 1 

답변

2

stackqueue 컨테이너 아니다; 그들은 어댑터 컨테이너입니다. 그들은 을 템플릿 인수로 사용하는 컨테이너 유형을 사용합니다. 기본적으로 그들은 std::deque을 사용합니다.

이와 같이, 그들은 적응시키고있는 컨테이너의 noexcept 동작을 전달합니다. 따라서 deque이 움직이면 deque을 사용하는 stack도 마찬가지입니다. 사실, 컨테이너 어댑터 이 해당 구성 요소 컨테이너의 noexcept 동작을 전달하지 않습니다. 또는 최소한 표준을 따르지 않아도됩니다.

실제 컨테이너의 noexcept 상태는 vectornoexcept 이동이 필요합니다 (이전에는 요구 사항이 없었 음). 나머지는 구현에 따라 다릅니다.

2

vector의 이동 생성자는 noexcept이고 C++ 17부터 만 보장됩니다.

deque, stackqueue 이동 생성자는 noexcept이 아닙니다. LLVM의 구현이 noexcept이라는 사실은 표준에 위배되지 않는 멋진 추가 기능입니다.

deque::swap()을보고 싶을 수도 있고 비슷한 기능을 제공하며 noexcept (C++ 17 이후)입니다.