Is the move-constructors noexcept property for containers implementation defined? I just found out that the following will work in clang but not in gcc or msvc++:
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
My question is, if this is caused by an incomplete implementation of the standard or if it is simply not defined (on purpose?).
I tested a few of the standard containers:
#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
clang 5.0.0:
Deque: 1
Vector: 1
Queue: 1
Stack: 1
Microsoft C/C++ Version 19.00.23506 for x64:
Deque: 0
Vector: 1
Queue: 0
Stack: 0
EDIT
Results for queue and stack using a vector as underlying container:
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
clang 5.0.0:
Vector Stack: 1
Vector Queue: 1
Microsoft C/C++ Version 19.00.23506 for x64:
Vector Stack: 1
Vector Queue: 1
stack and queue are not containers; they are container adapters. They use a container type that you give them as a template argument. By default, they use std::deque.
As such, they forward the noexcept behavior of the container they're adapting. So if Actually, container adapters don't forward the noexcept behavior of their component containers. Or at least, they aren't required to by the standard.deque throws on move, so too will a stack that uses a deque.
As for the noexcept status of actual containers, vector is required to have a noexcept move (this was a C++17 change; there were no requirements previously). The rest are implementation-dependent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With