Я на Visual Studio 2017. Недавно, поскольку мне не нравились несоответствующие стандарты С++, я пошел дальше и отключил нестандартные расширения языка в параметрах. Все идет нормально. Теперь у меня проблема.
#include <iostream>
#include <vector>
struct Vertex
{
Vertex(float pos) { }
Vertex(Vertex& other) { }
};
std::vector<Vertex> arrayOfVertices;
int main()
{
arrayOfVertices.emplace_back(7.f);
}
Это не будет компилироваться в Visual Studio, единственная ошибка, которую он дает:
"в компиляторе произошла внутренняя ошибка"
Если я включаю языковые расширения, он компилируется отлично. Если я не буду убирать языковые расширения и сделать конструктор копии с помощью const Vertex&
, он компилируется отлично.
Итак, я попытался использовать GCC в некоторых онлайн-компиляторах, и если конструктор копирования не принимает аргумент ссылки на константу, он не будет компилироваться, предоставляя различные ошибки. Тот, который, казалось, имел наибольший смысл:
ошибка: недействительная инициализация неконстантной ссылки типа "Vertex & из rvalue типа" Vertex
Я думал, что конструкторы копирования не обязательно должны быть const, в моем случае я хотел бы что-то изменить в другой ссылке. Я знаю, что аргументы non-const не могут принимать ссылки r-value, но я тестировал их, и получается, что в vector::emplace_back()
конструктор копирования вообще не вызывается:
#include <iostream>
#include <vector>
struct Vertex
{
Vertex(float pos)
{
std::cout << "Calling constructor\n";
}
Vertex(const Vertex& other)
{
std::cout << "Calling copy constructor\n";
}
};
std::vector<Vertex> arrayOfVertices;
int main()
{
arrayOfVertices.emplace_back(7.f); // Normal constructor called if const,
// doesn't compile if non-const
auto buff = malloc(sizeof(Vertex)); // Placement new
new (buff) Vertex(7.f); // Normal constructor called whether const
// or non-const. This is what I thought emplace_back did
}
Поэтому я понятия не имею, что происходит. Сначала я хотел бы знать, почему это происходит, если конструктор копирования не вызывается, а также если есть способ взять неконтент в моем конструкторе копирования в этом случае, то есть с помощью vector::emplace_back()
, потому что он похоже, эта проблема возникает только при использовании vector::emplace_back()
.