Visual Studio 2012 で非常に奇妙なことに気付きました: ペア オブジェクトを次のように定義します。
auto objp = pair<int, LogMe>();
VC11 のペアのコピー/移動を省略しません。この呼び出しは次のように表示されます。
LogMe::LogMe - def.ctor!
LogMe::LogMe - move.ctor!
LogMe::~LogMe - dtor!
つまり、一時的なペアが作成され、objp 変数に移動されます。(pair<...> obj;
デフォルトの ctor のみをログに記録すると宣言する)
LogMe テスト オブジェクトだけでクロス チェックしました。
cout << "# Construct Object via auto obj = ...\n";
auto obj = LogMe();
# Construct Object via auto obj = ...
LogMe::LogMe - def.ctor!
ここで割り当ては省略されます。
IDEOne (gcc 4.8.1 を使用) でテストすると、無関係な移動が常に省略されていることが示されるため、これは VC11 に固有のようです。
何が起きてる? 初期化コピーが省略されていることに頼ることができないことは、私を緊張させます。
注: リリース バージョンとデバッグ バージョンのテストでは、同じ結果が表示されます。(MSVCの最適化フラグとは無関係にコピー省略が実行されるため、これは予想していたでしょう。)
テストする完全なソースコード ( ideone リンクも参照):
#include "stdafx.h"
#include <iostream>
#include <map>
using namespace std;
struct LogMe {
std::string member;
LogMe() {
cout << __FUNCTION__ << " - def.ctor!" << endl;
}
~LogMe() {
cout << __FUNCTION__ << " - dtor!" << endl;
}
LogMe(LogMe const&) {
cout << __FUNCTION__ << " - cpy.ctor!" << endl;
}
LogMe& operator=(LogMe const&) {
cout << __FUNCTION__ << " - cpy.assign.op!" << endl;
return *this;
}
LogMe(LogMe&&) {
cout << __FUNCTION__ << " - move.ctor!" << endl;
}
LogMe& operator=(LogMe&&) {
cout << __FUNCTION__ << " - move.assign.op!" << endl;
return *this;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
{
cout << "# Construct Object via auto obj = ...\n";
auto obj = LogMe();
cout << "# Construct pair<int, object> via auto objp = ...\n";
auto objp = pair<int, LogMe>();
cout << "# Construct pair<int, object> via pair objp2; ...\n";
pair<int, LogMe> p2;
}
return 0;