Рассмотрим следующий код:
#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(), но не должен перераспределять что-либо.