Don*_*tch 6 c++ stdvector stdinitializerlist braced-init-list
我可以简洁地(用大括号)初始化以下 6 种情况中的 5 种:
\n| 可复制的 | 只移动的 | |
|---|---|---|
| 大批 | 是的 | 是的 |
| 标准::数组 | 是的 | 是的 |
| std::向量 | 是的 | 不 |
一种似乎不起作用的情况是尝试初始化仅移动对象的 std::vector ;无法编译,并显示消息,例如:“错误:调用 \'std::unique_ptr\' 的隐式删除复制构造函数”。
\n为什么是这样?是否有适用于这种情况的替代初始化语法?
\n下面的程序演示了。
\n/*\nclang++ -std=c++14 -W -Wall -Werror question.cc -o question\nclang++ -std=c++17 -W -Wall -Werror question.cc -o question\nclang++ -std=c++20 -W -Wall -Werror question.cc -o question\nclang++ -std=c++2b -W -Wall -Werror question.cc -o question\ng++ -std=c++14 -W -Wall -Werror question.cc -o question\ng++ -std=c++17 -W -Wall -Werror question.cc -o question\ng++ -std=c++20 -W -Wall -Werror question.cc -o question\ng++ -std=c++2b -W -Wall -Werror question.cc -o question\n*/\n#include <array>\n#include <memory>\n#include <vector>\n\nint main(int, char **) {\n {\n // I can initialize an array, std::array, or std::vector of\n // copyable objects concisely as follows:\n std::shared_ptr<int> a[] = {std::make_shared<int>(42)};\n std::shared_ptr<int> b[] {std::make_shared<int>(42)};\n std::array<std::shared_ptr<int>, 1> c = {std::make_shared<int>(42)};\n std::array<std::shared_ptr<int>, 1> d {std::make_shared<int>(42)};\n std::vector<std::shared_ptr<int>> e = {std::make_shared<int>(42)};\n std::vector<std::shared_ptr<int>> f {std::make_shared<int>(42)};\n }\n {\n // And I can also initialize an array or std::array (but not a std::vector)\n // of move-only (non-copyable) objects similarly:\n std::unique_ptr<int> a[] = {std::make_unique<int>(42)};\n std::unique_ptr<int> b[] {std::make_unique<int>(42)};\n std::array<std::unique_ptr<int>, 1> c = {std::make_unique<int>(42)};\n std::array<std::unique_ptr<int>, 1> d {std::make_unique<int>(42)};\n\n // But if I try to do the same with std::vector of move-only\n // objects, it fails to compile.\n // clang++:\n // "error: call to implicitly-deleted copy constructor\n // of \'std::unique_ptr<int>\'"\n // g++ (c++14, c++17):\n // "error: static assertion failed: result type must be constructible\n // from input type"\n // g++ (g++20, g++2b):\n // "error: use of deleted function\n // \xe2\x80\x98std::unique_ptr<_Tp, _Dp>::unique_ptr(\n // const std::unique_ptr<_Tp, _Dp>&)\n // [with _Tp = int; _Dp = std::default_delete<int>]\xe2\x80\x99\n#if 1 // (hard code to 1 for error, 0 for successful compile)\n std::vector<std::unique_ptr<int>> e = {std::make_unique<int>(42)};\n std::vector<std::unique_ptr<int>> f {std::make_unique<int>(42)};\n#endif\n // The most concise workaround I have found is as follows.\n // (This would not work if I wanted to make the vector const.)\n // Notice that initializer-list initialization does succeed,\n // as long as the initializer list is empty!\n std::vector<std::unique_ptr<int>> e_workaround = {};\n e_workaround.push_back(std::make_unique<int>(42));\n std::vector<std::unique_ptr<int>> f_workaround {};\n f_workaround.push_back(std::make_unique<int>(42));\n }\n\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n
您尝试调用的构造函数是(https://en.cppreference.com/w/cpp/container/vector/vector)
Run Code Online (Sandbox Code Playgroud)vector( std::initializer_list<T> init, const Allocator& alloc = Allocator() );
(constexpr自 C++20 起)
参数是 a std::initializer_list<T>, 按值。您的电话与以下内容没有什么不同:
auto u = std::make_unique<int>(42);
std::vector<std::unique_ptr<int>> e = {u};
Run Code Online (Sandbox Code Playgroud)
如果这从 开始u,那将是一个糟糕的意外。另一方面,移动 astd::initializer_list几乎没有什么用处,因为它只是一个数组的轻量级代理T(复制 astd::initializer_list并不复制元素)。
std::array您的原始 c 数组代码可以工作,因为它是聚合初始化。那里不std::initializer_list涉及构造函数。
解决方法看起来没问题。您可以编写一个函数来初始化向量
/*const*/ std::vector<std::unique_ptr<int>> e = from_ints({42,2,31});
Run Code Online (Sandbox Code Playgroud)
当向量为 时,这也适用const。
| 归档时间: |
|
| 查看次数: |
130 次 |
| 最近记录: |