次のコードを検討してください。
#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
(つまり、実際にコンストラクターを呼び出そうとするクラス) は実装固有です (たとえば、 GCC__gnu_cxx::new_allocator<A>
です)。EDIT : このようなフレンド宣言により、誰でもemplace_back()
A
プライベート コンストラクターを使用してA
's のコンテナーを作成できるようになるため、実際には何も解決しないことに気付きました。その時点でコンストラクターをパブリックにすることもできます...
UPDATE :A
移動コンストラクターが高価であることだけが、それを呼び出さなくてもよい理由ではないことを追加する必要があります。A
まったく移動できない(コピーもできない)可能性があります。vector
もちろん、それは(emplace_back()
ベクトルを再割り当てする必要があるかもしれないため) では機能しませんがdeque
、同様の方法を持ちますが、何も再割り当てする必要がない では機能します。emplace_back()