考慮下面的代碼:問題努力構建'的std :: VECTOR`與初始化列表
#include <memory>
#include <vector>
class A {
public:
explicit A(std::vector<int> &&v) : v_(std::move(v)) {}
private:
std::vector<int> v_;
};
int main() {
// compilation error (no matching call to std::make_unique)
// compiler output: https://ideone.com/4oKjCS
std::vector<std::unique_ptr<A>> as1 = {std::make_unique<A>({1}),
std::make_unique<A>({2})};
// compilation error (requested copy of std::unique_ptr)
// compiler output: https://ideone.com/5LGPoa
std::vector<std::unique_ptr<A>> as2 = {
std::make_unique<A>(std::vector<int>({1})),
std::make_unique<A>(std::vector<int>({2}))};
// succeeds
std::vector<std::unique_ptr<A>> as3;
as3.push_back(std::make_unique<A>(std::vector<int>({1})));
as3.push_back(std::make_unique<A>(std::vector<int>({2})));
}
- 對於
as1
:我希望std::make_unique<A>({1})
調用std::vector
隱含的初始化列表構造,然後傳遞矢量到std::make_unique
。爲什麼不編譯? - 對於
as2
:std::make_unique
的結果是一個右值。爲什麼要在任何地方提交副本? - 有沒有比我的
as3
更有地道或更短的方式來完成這項工作?
編輯:我現在記得as1
中的錯誤原因。 Meyers'Effective Modern C++在第30條中提到了初始值設定項列表作爲完美轉發的失敗情況之一:「將標準初始化程序傳遞給函數模板參數(未聲明爲std::initializer_list
)被規定爲,如標準所示,「未推斷的上下文」。「
「int」的例子在任何情況下都可以正常工作,因爲'new int'只能拋出'bad_alloc',從中無法恢復。自定義數據類型的構造函數可能會拋出更多的問題,因爲那樣你會從原始指針的部分初始化向量中泄漏內存。 'emplace_back'解決方案是唯一的故障安全解決方案。 (1) –