如何方便地构造一个 unique_ptr 指向具有单个元素的向量?
How can I construct a unique_ptr pointing to a vector with single element conveniently?
我想构建一个 unique_ptr
持有一个 vector<string>
,它只包含一个元素。是否可以在单行代码中执行此操作?
我尝试这种方法:
auto values = make_unique<vector<string>>({value});
但是编译器 (clang++) 抱怨:
No matching function for call to 'make_unique' candidate template ignored:
substitution failure [with _Tp = std::__1::vector<std::__1::basic_string<char>, std::__1::allocator<std::__1::basic_string<char> > >]: no type named '__unique_array_unknown_bound' in 'std::__1::__unique_if<st... candidate template ignored: substitution failure [with _Tp = std::__1::vector<std::__1::basic_string<char>, std::__1::allocator<std::__1::basic_string<char> > >]: no type named '__unique_array_known_bound' in 'std::__1::__unique_if<std:... candidate function [with _Tp = std::__1::vector<std::__1::basic_string<char>, std::__1::allocator<std::__1::basic_string<char> > >, _Args = <>] not viable: requires 0 arguments, but 1 was provided
我不明白为什么它不起作用,因为 vector
显然接受使用 initializer_list
进行构造。
string value = ...;
auto values = vector<string>({value}); // this works
创建 unique_ptr<vector<string>>
并调用其 push_back
是构建此类 unique_ptr
的唯一可行方法吗?
auto values = make_unique<vector<string>>();
values->push_back(value);
更广泛地说,如果我有固定数量的元素(例如 3 个元素),并且想构建一个 unique_ptr
包含这些元素的向量,惯用的方法是什么?
出现在函数调用中的 {...}
不是初始化列表(除非函数明确要求 std::initializer_list
);如果它被用来直接初始化某些东西(例如,在赋值的右侧,或在 range-for 循环中),它只是一个初始化列表。
如果你真的想传递一个初始化列表,你可以明确地这样做:
auto values = std::make_unique<std::vector<std::string>>(
std::initializer_list<std::string>{ value });
您也可以只构建一个临时向量并将其传入:
auto values = std::make_unique<std::vector<std::string>>(std::vector<std::string>{ value });
或使用 C++17 CTAD:
auto values = std::make_unique<std::vector<std::string>>(std::vector{ value });
这将推广到任意数量的固定元素。如果你只想要一个包含三个元素的向量而不关心值,你可以使用 std::vector
的 "count" 构造函数:
auto values = std::make_unique<std::vector<std::string>>(3);
// values contains three empty strings
如果value
是局部变量,可以使用iterator构造函数。否则,您可以直接使用 new
来使用初始化列表构造函数。
using string_vec = std::vector<std::string>;
auto values = std::make_unique<string_vec>(&value, &value + 1);
auto values = std::unique_ptr<string_vec>(new string_vec{ value });
当然,第二种方式很容易推广到小型固定大小的初始值设定项,例如 new string_vec{ value_1, value_2, value_3 }
。使用第一种方法,您必须将它们存储在 std::string[3]
中,然后只传递其中的 begin/end。
我想构建一个 unique_ptr
持有一个 vector<string>
,它只包含一个元素。是否可以在单行代码中执行此操作?
我尝试这种方法:
auto values = make_unique<vector<string>>({value});
但是编译器 (clang++) 抱怨:
No matching function for call to 'make_unique' candidate template ignored:
substitution failure [with _Tp = std::__1::vector<std::__1::basic_string<char>, std::__1::allocator<std::__1::basic_string<char> > >]: no type named '__unique_array_unknown_bound' in 'std::__1::__unique_if<st... candidate template ignored: substitution failure [with _Tp = std::__1::vector<std::__1::basic_string<char>, std::__1::allocator<std::__1::basic_string<char> > >]: no type named '__unique_array_known_bound' in 'std::__1::__unique_if<std:... candidate function [with _Tp = std::__1::vector<std::__1::basic_string<char>, std::__1::allocator<std::__1::basic_string<char> > >, _Args = <>] not viable: requires 0 arguments, but 1 was provided
我不明白为什么它不起作用,因为 vector
显然接受使用 initializer_list
进行构造。
string value = ...;
auto values = vector<string>({value}); // this works
创建 unique_ptr<vector<string>>
并调用其 push_back
是构建此类 unique_ptr
的唯一可行方法吗?
auto values = make_unique<vector<string>>();
values->push_back(value);
更广泛地说,如果我有固定数量的元素(例如 3 个元素),并且想构建一个 unique_ptr
包含这些元素的向量,惯用的方法是什么?
{...}
不是初始化列表(除非函数明确要求 std::initializer_list
);如果它被用来直接初始化某些东西(例如,在赋值的右侧,或在 range-for 循环中),它只是一个初始化列表。
如果你真的想传递一个初始化列表,你可以明确地这样做:
auto values = std::make_unique<std::vector<std::string>>(
std::initializer_list<std::string>{ value });
您也可以只构建一个临时向量并将其传入:
auto values = std::make_unique<std::vector<std::string>>(std::vector<std::string>{ value });
或使用 C++17 CTAD:
auto values = std::make_unique<std::vector<std::string>>(std::vector{ value });
这将推广到任意数量的固定元素。如果你只想要一个包含三个元素的向量而不关心值,你可以使用 std::vector
的 "count" 构造函数:
auto values = std::make_unique<std::vector<std::string>>(3);
// values contains three empty strings
如果value
是局部变量,可以使用iterator构造函数。否则,您可以直接使用 new
来使用初始化列表构造函数。
using string_vec = std::vector<std::string>;
auto values = std::make_unique<string_vec>(&value, &value + 1);
auto values = std::unique_ptr<string_vec>(new string_vec{ value });
当然,第二种方式很容易推广到小型固定大小的初始值设定项,例如 new string_vec{ value_1, value_2, value_3 }
。使用第一种方法,您必须将它们存储在 std::string[3]
中,然后只传递其中的 begin/end。