22

これらの機能は同等ですか?

template <class T>
void foo(T && t)
{
    bar(std::forward<T>(t));
}

template <class T>
void foo2(T && t)
{
    bar(std::forward<decltype(t)>(t));
}

template <class T>
void foo3(T && t)
{
    bar(std::forward(t));
}

そうである場合、このマクロを常に使用して完全な転送を行うことはできますか?

#define MY_FORWARD(var) std::forward<decltype(var)>(var)

または単に使用する

bar(std::forward(t));

私はfoo2foo3は同じだと信じていますが、人々は常に forward like を使用していることがわかりましfooた。型を明示的に記述する理由はありますか?

Tとは 2 つの異なるタイプであることは理解していますが、 とは常に同じ結果になるT&&と思いますか?std::forward<T>std::forward<T&&>


編集:

マクロを使用したい理由は、次の C++1y コードの入力を節約したいからです。さまざまな場所に多くの同様のコードがあります。

#define XLC_FORWARD_CAPTURE(var) var(std::forward<decltype(var)>(var))
#define XLC_MOVE_CAPTURE(var) var(std::move(var))

template <class T, class U>
auto foo(T && func, U && para )
{
    auto val = // some calculation
    return [XLC_FORWARD_CAPTURE(func),
            XLC_FORWARD_CAPTURE(para),
            XLC_MOVE_CAPTURE(val)](){
              // some code use val
              func(std::forward<U>(para)); 
          };
}
4

2 に答える 2

17

これらの機能は2 つ同等ですか?

はい、同等です。decltype(t)は と同じでT&&あり、 と一緒に使用する場合、何が何であるかに関係なく、とstd::forwardの間に違いはありません。TT&&T

完全な転送のためにこのマクロを常に使用できますか?

はい、できます。コードを読みにくく、保守できないようにしたい場合は、そうしてください。しかし、私は強くお勧めしません。一方では、このマクロを使用しても基本的に何も得られません。その一方で、他の開発者は、定義を理解するために定義を確認する必要があり、微妙なエラーが発生する可能性があります。たとえば、括弧を追加しても機能しません。

MY_FORWARD((t))

対照的に、 の形式decltypeは完全に有効です。特に、明示的な型パラメーターがないため、一般的なラムダ式からパラメーターを転送する方法として推奨されます。

[](auto&& t) { foobar(std::forward<decltype(t)>(t)); }

std::forward(t)有効ではないため、 で3 番目のバリアントを無視しました。


更新:あなたの例について: function templateのcall-by-reference の代わりにcall -by-valueを使用できます。次に、代わりに使用できます。これにより、コードに 2 つの移動が追加されますが、追加のコピー操作はありません。一方、コードはよりきれいになります。foostd::movestd::forward

template <class T, class U>
auto foo(T func, U para)
{
    auto val = // some calculation
    return [func=std::move(func),para=std::move(para),val=std::move(val)] {
        // some code use val
        func(std::move(para)); 
    };
}
于 2014-04-27T08:56:39.023 に答える