Рассмотрим следующий код:
#include <vector>
class A
{
public:
A(A&&); // somewhat expensive
static std::vector<A> make_As()
{
std::vector<A> result;
result.push_back(A(3));
result.push_back(A(4));
return result;
}
private:
A(int); // private constructor
};
Так как конструктор move A
несколько дорог (по какой-либо причине), я бы хотел не называть его и вместо него использовать emplace_back()
:
#include <vector>
class A
{
public:
A(A&&); // somewhat expensive
static std::vector<A> make_As()
{
std::vector<A> result;
result.emplace_back(3);
result.emplace_back(4);
return result;
}
private:
A(int); // private constructor
};
К сожалению, при emplace_back()
фактический вызов конструктора выполняется чем-то в стандартной библиотеке, которая недостаточно привилегирована, чтобы иметь возможность вызывать частный конструктор A
.
Я понимаю, что, возможно, мало что можно сделать по этому поводу, но, тем не менее, я чувствую, что, поскольку вызовы emplace_back()
встречаются внутри члена A
, они должны иметь возможность вызвать частный конструктор.
Есть ли какие-либо обходные пути для этого?
Единственное, что я могу придумать, это добавить объявление друга в A
, но точный класс, который должен быть A
friend (то есть класс, который на самом деле пытается вызвать конструктор), - это реализация (например, для GCC it __gnu_cxx::new_allocator<A>
). РЕДАКТИРОВАТЬ: только что понял, что такое объявление друга позволит любому emplace_back()
A
, сконструированному с помощью частного конструктора, в контейнер A
, поэтому он ничего не решит, Я мог бы также сделать конструктор открытым в этот момент...
UPDATE. Я должен добавить, что конструктор перемещения A
, являющийся дорогостоящим, не является единственной причиной, почему бы не называть его. Возможно, что A
вообще не перемещается (и не копируется). Это, конечно, не работает с vector
(потому что emplace_back()
может потребоваться перераспределить вектор), но это будет с deque
, который также имеет аналогичный метод emplace_back()
, но не должен перераспределять что-либо.