#опытным
Довольно часто приходится работать с plain old data типами. Они не имеют никаких специальных методов и конструкторов, это просто структуры с полями. Например:
struct Point {
int x;
int y;
int z;
}Создают объекты таких типов с помощью синтаксиса универсальной инициализации через фигурные скобки {}:
Point p{1, 2, 3};
Point p(1, 2, 3); // WrongПри этом через круглые скобки создать объект такого класса нельзя.
С повсеместным использованием универсальной инициализации с точки зрения код стайла создание таких объектов даже не выбивается из общего кода.
Но все-таки у этого есть проблемы.
Часто такие структурки хочется хранить в каком-нибудь векторе. Для добавления в вектор можно использовать push_back и emplace_back. Использование emplace_back выгоднее по перформансу, поэтому нужно обычно использовать именно этот метод.
Но с POD типами он работает хреново.
std::vector<Point> vec;
vec.emplace_back(1, 2, 3); // Error!
Вот так вы написать не можете. emplace_back под капотом использует создание объекта с помощью new именно через круглые скобки. А как мы помним, так инициализировать POD типы нельзя.
Поэтому приходится в этих случаях явно конструировать объект и вызывать мув-конструктор:
vec.emplace_back(Point{1, 2, 3});что убивает преимущества emplace_back перед push_back. Либо можно использовать непросредственно push_back.
Та же проблемы и в использовании функций std::make_*. Под капотом они тоже используют new с круглыми скобками и просто невозможно нормально использовать эти функции. Приходится явно вызывать new с фигурными скобками, что усугубляет проблему:
std::unique_ptr<Point>(new Point{1, 2, 3}); Конечно кейс с emplace_back намного чаще встречается в практике. POD типам не нужны фабличные методы и, обычно, контроль времени жизни.
В общем, не жизнь, а страдания.
Однако есть свет в конце тоннеля! Но об этом в следующий раз.
See the light. Stay cool.
#cppcore