2

私のコードには、T&&またはconstT&に遭遇したときに関数の反応がわずかに異なるインスタンスがいくつかありますが、関数自体は非常に長いです(Tは単なるオブジェクトタイプであることに注意してください)。例えば:

void push_back(const T& newt){
    /* code block X */
    new (ptr) T(newt);
    /* code block Y */
}

void push_back(T&& newt){
    /* code block X */
    new (ptr) T(std::move(newt));
    /* code block Y */
}

この擬似コードの線に沿って何かを書くことは可能ですか?

template<typename S>
void push_back(S newt){
    /* code block X */
#if decltype(newt)==T&&
    new (ptr) T(std::move(newt));
#else
    new (ptr) T(newt);
#endif
    /* code block Y */
}

または、ほぼ同じ移動およびコピー関数を作成するためのより良い方法はありますか?

4

1 に答える 1

5

関数で使用std::forward()し、T&&関数を破棄しconst T&ます。

template <typename T>
void push_back(T&& newt){
    /* code block X */
    new (ptr) typename std::remove_reference<T>::type(std::forward<T>(newt));
    /* code block Y */
}

std::forward()は、に渡されたnewtとおりに渡されpush_back()ます。その結果:

  • 左辺値が渡されたT場合に使用されるコピー コンストラクター、またはpush_back()
  • 右辺値が渡されたT場合に使用される移動コンストラクター。push_back()

http://ideone.com/HjOrapでオンライン デモを参照してください。

push_back()が独立した関数または非テンプレート クラスのメンバー関数である場合、これは正しいことに注意してください。Tテンプレート クラス メンバー関数の場合、この動作は推定型であることに依存するため、関数自体がクラス テンプレート型に加えてテンプレート型を受け入れる必要があります。

Scott Meyers によるUniversal Referencesを参照してください。

于 2013-02-13T21:43:48.837 に答える