[英]Emplacement of a vector with initializer list
我有一個std::vector<std::vector<double>>
並想在它的末尾添加一些元素,所以這是我的試驗:
std::vector<std::vector<double> > vec;
vec.emplace_back({0,0});
但這不會編譯,而以下將執行:
std::vector<double> vector({0,0});
為什么 emplace_back 不能在這個位置構造元素? 或者我做錯了什么?
謝謝你的幫助。
前面的答案提到,當您在線構造向量並放置它時,您可以獲得要編譯的代碼。 但是,這意味着您正在臨時向量上調用移動構造函數,這意味着您沒有就地構造向量,而這就是使用emplace_back
而不是push_back
的全部原因。
相反,您應該將初始化列表轉換為一個initializer_list
,如下所示:
#include <vector>
#include <initializer_list>
int main()
{
std::vector<std::vector<int>> vec;
vec.emplace_back((std::initializer_list<int>){1,2});
}
模板推導無法猜測您的大括號括起來的初始化列表應該是一個向量。 你需要明確:
vec.emplace_back(std::vector<double>{0.,0.});
請注意,這會構造一個向量,然后使用std::vector
的移動復制構造函數將其移動到新元素中。 所以在這種特殊情況下,它沒有超過push_back()
優勢。 @TimKuipers 的回答顯示了解決此問題的方法。
這里真的有兩個問題:數字類型轉換和模板參數推導。
允許std::vector<double>
構造函數對其std::vector<double>(std::initializer_list<double>)
構造函數使用花括號列表(甚至是int
std::vector<double>(std::initializer_list<double>)
。 (但是請注意, std::initializer_list<int>
不會隱式轉換為std::initializer_list<double>
)
emplace_back()
不能從大括號表達式構造元素,因為它是一個使用完美轉發的模板。 標准禁止編譯器推斷{0,0}
的類型,因此std::vector<double>::emplace_back<std::initializer_list<double>>(std::initializer_list<double>)
不會被編譯對於emplace_back({})
。
其他答案指出, emplace_back
可以為std::initializer_list<vector::value_type>
類型的參數編譯,但不會直接從{}
表達式推導出此類型。
作為將參數轉換為emplace_back
的替代方法,您可以先構造參數。 正如 Meyers 的 Item 30 (Effective Modern C++) 所指出的,允許auto
將大括號表達式的類型推導出為std::initializer_list<T>
,並且允許完美轉發推導出其類型被推導的對象的類型通過auto
。
std::vector<std::vector<double> > vec;
auto double_list = {0., 0.}; // int_list is type std::initializer_list<int>
vec.emplace_back(double_list); // instantiates vec.emplace_back<std::initializer_list<double>&>
emplace_back
通過調用std::vector<double>(std::forward<std::initializer_list<double>>(double_list))
向vec
添加一個元素,這會觸發std::vector<double>(std::initializer_list<double>)
構造函數。
參考:第 17.8.2.5 節第 5.6 項表明這是一個非推導上下文,用於 17.8.2.1 第 1 項下的模板參數推導。
更新:此答案的早期版本錯誤地暗示可以提供std::initializer_list<int>
代替std::initializer_list<double>
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.