いいえ良い方法はありません。 HeroicKatora's commentは、私が知っている唯一の可能性です:メッセージがコピー構築され、構築されたときにメッセージを出力するカスタムアロケータを構築します。しかし、問題があります...
カスタムアロケータをビルドするには、私のallocator boilerplate(著作権、参照、またはリンクは必要ありません)を使用して自由に感じてください。これは単なるスケルトンアロケータです。特別なものは何もない。私はこの質問に対して次のストローマンアロケータを作成するために、これを使用しました
:
template <class T>
class allocator
{
public:
using value_type = T;
allocator() = default;
allocator(allocator const&) = default;
allocator(allocator&&)
{
std::cout << "container move construction\n";
}
template <class U> allocator(allocator<U> const&) noexcept {}
value_type* // Use pointer if pointer is not a value_type*
allocate(std::size_t n)
{
return static_cast<value_type*>(::operator new (n*sizeof(value_type)));
}
void
deallocate(value_type* p, std::size_t) noexcept // Use pointer if pointer is not a value_type*
{
::operator delete(p);
}
allocator
select_on_container_copy_construction() const
{
std::cout << "container copy construction\n";
return *this;
}
};
template <class T, class U>
bool
operator==(allocator<T> const&, allocator<U> const&) noexcept
{
return true;
}
template <class T, class U>
bool
operator!=(allocator<T> const& x, allocator<U> const& y) noexcept
{
return !(x == y);
}
コンテナコピー構造、コピー構築コンテナのアロケータを取得するためにstd::allocator_traits<your_allocator>::select_on_container_copy_construction()
を呼び出すために必要とされます。アロケータでこの関数を実装しないと、std::allocator_traits
はアロケータのコピーを返します。私はこのデフォルトの動作をオーバーライドしてメッセージを出力しました。
コンテナを移動するときは、アロケータを構築する必要があります。そこで、allocator
移動コンストラクタを変更してメッセージを出力しました。
問題この方法では、コンテナがアロケータを1回だけ移動またはコピーする必要はありません。
template <class T> using vector = std::vector<T, allocator<T>>;
template <class T> using deque = std::deque<T, allocator<T>>;
int
main()
{
vector<int> v;
std::cout << "Begin move\n";
auto v2 = std::move(v);
std::cout << "End move\n";
std::cout << "Begin copy\n";
auto v3 = v2;
std::cout << "End copy\n";
}
GCC出力:
Begin move
container move construction
End move
Begin copy
container copy construction
End copy
Visual Studioがコピーに無償移動構成を追加します
GCCは、このドライバのための理想的な結果を提供し、例えば、容器としてvector
を使用
Begin move
container move construction
End move
Begin copy
container copy construction
container move construction
End copy
LLVMのlibC++は、移動の構成を2倍にします。要約すると、不満足な「並べ替え」である。 : - \
本当にひどい考えです。可能なプロファイリングツールと静的解析ツールを代わりに使用します。 –
私の頭の上からのベストアイデアはカスタムアロケータですが、それは追跡するすべてのインスタンスの宣言ポイントを制御する場合にのみ機能します。 – HeroicKatora
もう1つの注意: 'namespace std'(' std :: move'などの実装を含む)内にあるものを宣言すると、未定義の動作になります。 – HeroicKatora