2016-04-25 17 views
-2

this(信じられないほどよく書かれた)記事については、転送参考をScott Meyersが受け取りました。今C++:転送に関する参照

、記事のこの部分に焦点を当てる:

template <class... Args> 
void emplace_back(Args&&... args); // deduced parameter types ⇒ type deduction; 
...        // && ≡ universal references 

ので、他の例とは対照的に、楕円は&&右辺値参照を作成しませんが、それはまだ普遍的な参照です。私が理解したものから

、我々は普遍的な参照を持っているとき、私たちは(、すごいかっこいい!)右辺と左辺値の両方を渡して関数を呼び出すことができ

さて、私はこの機能を実装しました:

template <typename ReturnType, typename... Args> 
ReturnType callFunction(MemFunc<ReturnType, Args...> memFunc, Args&& ... args) { ... 

したがって、前述の例と同じロジックを使用して、&&は転送参照を意味します。

しかし、私はこの呼び出しにしようとします

typedef vector<double> vecD; 
vecD vec; 
mem.callFunction<vecD, vecD>(sortFunc, vec); 

をコンパイラはこれが起こるのはなぜYou cannot bind an lvalue to an rvalue reference

と文句を言うために起こっていますか?

WHOLE CODE:だから最初

#include <functional> 
#include <vector> 

using namespace std; 
struct MultiMemoizator { 
    template <typename ReturnType, typename... Args> 
    ReturnType callFunction(std::function<ReturnType(Args...)> memFunc, Args&&... args) { 

    } 
}; 

typedef vector<double> vecD; 

vecD sort_vec (vecD const& vec) { 
    return vec; 
} 

int main() 
{ 
    vecD vec; 
    std::function<vecD(vecD)> sortFunc(sort_vec); 
    MultiMemoizator mem; 
    mem.callFunction<vecD, vecD>(sortFunc, vec); 
} 
+5

*ユニバーサル*参考文献は非常に初めからひどい言葉でしたが、最終的にははるかに適切な*フォワーディング*レフェレンスに置き換えられました。 – SergeyA

+2

あなたの呼び出しで 'Args'が実際に*推測*されていますか? –

+1

私は本当のMCVEを見たいです。スニペットからうまくいくはずです。 – SergeyA

答えて

7

オフ、 "転送リファレンス" の代わりに "ユニバーサルリファレンス" をご利用ください。それが何であり、その意図された用途が何であるかをよりよく表している。

最初に気づくべきことは、すべて&&が転送参照であるとは限りません。また、それは右辺値の参照でもあります。簡単に言えば

T&&は場合にのみ転送基準である:(次に示すような簡単な)

  • T簡単されるタイプ(SOインスタンスvector<int>&&又はvector<T>&&ため転送参照ありません)。
  • およびTが導かれる。

例では、Argsは推測されません。単純なもので

mem.callFunction<vecD, vecD>(sortFunc, vec); 
         ^~~~ 

レッツ仕事がよりよく理解するために:

struct X {}; 

template <class T> 
auto foo(T&& p) {} 

をシーンを設定できます、あなたがそれを呼び出すときに明示的関数テンプレート引数Argsを指定するためです

次の2通話では、転送先の参照先があります。

X x; 
foo(x); 

foo(X{}); 

最初に、はX&と導かれ、規則を破棄することによって:X& &&X&となるため、左辺参照があります。期待通りに第二に

Tしたがって、我々は右辺値参照を有する、XようX &&X&&なる崩壊規則によって推論されるであろう。

しかし、ときにこのようにそれを呼び出す:

foo<X>(x); 

Tはもはや推定されます。基本的には、TXとしましょう。したがってTXの場合、T &&X&&であり、タイプがX&&pは左辺値にバインドできません。


ホルトも追加:

Also note that because of the declaration of sortFunc, this would not work even if you did not specify the function template arguments explicitely.

を私は彼に同意する傾向があるが、私はこれを確認するために、さらに調査する必要があります。

+0

'sortFunc'の宣言のため、関数テンプレート引数を明示的に指定しなくても、これは機能しません。 – Holt

+0

私はあなたの答えを理解したと思うが、私の次の質問は:私のコードを "参照可能なもの"にする方法がある(そして 'Args'型が推測されるようにする) – justHelloWorld

+0

@justHelloWorld一見して、私はいいえと言います(少なくとも厄介な醜いハッキングはありません)。 'sortFunc'に' Args'を指定する必要があります。おそらく 'memFunc'を最後のパラメータ(それが可能であれば分かりません)にして、' Args'の控除が最初に起こるようにしますが、 'memFunc'の署名を変更します。しかし、 'remove_reference_t'を' memFuc'のパラメータのシグネチャに追加することができます。私が言ったように、醜い醜いハック。 – bolov

関連する問題