Добавление вектора со списком инициализаторов

у меня есть std::vector<std::vector<double>> и хотел бы добавить некоторые элементы в конце этого, так что это был мой пробный период:

std::vector<std::vector<double> > vec;
vec.emplace_back({0,0});

но это не компилируется, тогда как следующее будет делать:

std::vector<double> vector({0,0});

Почему emplace_back не может создать элемент в этой позиции? Или что я делаю не так?

Спасибо за вашу помощь.

10

Решение

Шаблонный вывод не может угадать, что заключенный в скобки список инициализации должен быть вектором. Вы должны быть явными:

vec.emplace_back(std::vector<double>{0.,0.});
7

Другие решения

В предыдущем ответе упоминалось, что вы можете получить код для компиляции, когда вы строите вектор в строке и используете его.
Это означает, однако, что вы вызываете конструктор перемещения для временного вектора, что означает, что вы не создаете вектор на месте, в этом и заключается вся причина использования 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});
}
13

std::vector<double> конструктору разрешено использовать ограниченный список intс его std::vector<double>(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<T> если он не должен выводить тип непосредственно из {} выражение. В качестве альтернативы приведению аргумента к emplace_backВы могли бы сначала построить аргумент. Как указано в пункте 30 Мейерса («Эффективный современный C ++»), auto разрешено выводить тип выражения фигурной скобки, а совершенная пересылка позволяет выводить тип объекта, тип которого был выведен auto,

std::vector<std::vector<double> > vec;
auto int_list = {0, 0}; // int_list is type std::initializer_list<int>
vec.emplace_back(int_list); // instantiates vec.emplace_back<std::initializer_list<int>>

emplace_back добавляет элемент к vec позвонив std::vector<double>(std::forward<std::initializer_list<int>>(int_list)), который вызывает std::vector<double>(std::initializer_list<double>) конструктор и элементы int_list конвертированы.

0
По вопросам рекламы [email protected]