4

この無害に見えるコードがかなり危険であると考えるのは正しいですか?

template<typename T>
void insertLast(std::vector<T>& v)
{
    if(v.empty()) return;  
    v.insert(v.begin(), v.back());
}

いくつかの回答を読んだ後のいくつかの説明..

要素をベクトルに挿入する方法を実際に尋ねているわけではありませんが、原則を疑問視するダミーの状況を作成しました..つまり、コピーを作成する必要があると思いますか (ここでは一時的なものが作成されます..そして const一時的な参照は有効であることが保証されています):

template<typename T>
void insertLast(std::vector<T>& v)
{
    if(v.empty()) return;  
    v.insert(v.begin(), T(v.back()));
}
4

2 に答える 2

2

vector.back() が参照を返すため、私にも危険に思えます。

ベクターの末尾以外の位置への挿入は、位置とベクターの末尾の間のすべての要素を新しい位置に移動してから、新しい要素を挿入することによって実行されます (ここから) 。

私が誤解しない限り、渡された参照はinsert「無効」になります(再割り当てが発生しない場合、最後の要素ではなく前の要素を含めることができます。そうでない場合は正しいかもしれませんが、保証されていないと思います.

場合によっては、一部のオプティマイザーがバグを隠す可能性があります (オブジェクトでは発生しないが、プリミティブでは発生する可能性があると思います)。そのため、期待どおりの結果が得られますが、一般的にはそのような動作には依存しません。

于 2012-09-28T16:00:35.620 に答える
1

これをコンパイルするためにコメントに記載されている 2 つのポイントに対処したと仮定すると、これは実行されますが、 vector.back() が参照を返すという事実のために、実行されるたびにベクトルの前にガベージ値が残ります。

これがやろうとしているように見えるのは次のとおりです。

template<typename T>
void insertLast(std::vector<T>& v)
{
    if(v.empty()) return;  
    v.insert(v.begin(), v.end() - 1, v.end());
}

これにより、ベクトルの最後の要素が安全に挿入されるため、最初の要素でもあります....それが望ましい動作であると仮定します。

于 2012-09-28T15:56:51.993 に答える