この質問は、C++11 標準ライブラリのいくつかの関数の仕様に関するものです。これらの関数は、引数を右辺値参照として受け取りますが、すべての場合にそれらを消費するわけではありません。一例は
std::unordered_set<T>::insert(T&&)
です。
T
コンテナ内に要素がまだ存在しない場合、このメソッドが移動コンストラクタを使用してコンテナ内に要素を構築することは明らかです。しかし、要素がコンテナーに既に存在する場合はどうなるでしょうか。この場合、オブジェクトを変更する理由はないと確信しています。ただし、私の主張を裏付ける C++11 標準には何も見つかりませんでした。
これが興味深い理由を示す例を次に示します。次のコードは std::cin から行を読み取り、最初に出現した重複行を削除します。
std::unordered_set<std::string> seen;
std::string line;
while (getline(std::cin, line)) {
bool inserted = seen.insert(std::move(line)).second;
if (!inserted) {
/* Is it safe to use line here, i.e. can I assume that the
* insert operation hasn't changed the string object, because
* the string already exists, so there is no need to consume it. */
std::cout << line << '\n';
}
}
どうやら、この例は GCC 4.7 で動作します。しかし、それが標準に従って正しいかどうかはわかりません。