簡體   English   中英

使用初始化列表放置向量

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM