2017-09-01 2 views
2

verstehe ich, dass eine Weiterleitungsreferenz ist „eine rvalue Bezugnahme auf einen CV-unqualifizierten Template-Parameter“, wie inC++ Weiterleitungsreferenz und rvalue Referenz

template <class T> void foo(T&&); 

was bedeutet, die obige Funktion sowohl L annehmen kann -value und r-Wert Referenz.

Es gibt etwas, das ich nicht verstehe, z.

template <class T> 
class A 
{ 
    template <class U> 
    void foo(T&& t, U&& u) 
    { 
     T t2(std::forward(t)); // or should it be std::move(t)? is T&& forwarding or r-value reference 
     U u2(std::forward(u)); // or should it be std::move(u)? I believe U&& is forwarding reference 
    } 
}; 

in dem obigen Code, sind beide T & & und U & & Forwarding Referenzen?

Ich schrieb einige Code (VS2015 Compiler) zu testen:

class A 
{ 
public: 
    A(){}; 
    A(const A& rhs) 
    { 
     std::cout << "calling 'const A&' l-value" << std::endl; 
    } 

    A(A&& rhs) 
    { 
     std::cout << "calling ' A&&' r-value" << std::endl; 
    } 

}; 

template <class T> 
class Test 
{ 
public: 
    void test1(T&& t) 
    { 
     T t2(std::forward<T>(t)); 
    } 

    template <typename X> 
    void test2(X&& x) 
    { 
     T t2(std::forward<T>(x)); 
    } 

}; 

void main() 
{ 
    A a; 
    Test<A> test; 
    test.test1(A()); 
    test.test1(std::move(a)); 
    //test.test1(a); // this doesn't compile. error: cannot convert argument 1 from 'A' to 'A &&', You cannot bind an lvalue to an rvalue reference 

    test.test2<A>(A()); 
    test.test2<A>(std::move(a)); 

    //test.test2<A>(a); // this doesn't compile. error: cannot convert argument 1 from 'A' to 'A &&', You cannot bind an lvalue to an rvalue reference 
} 

Ich hatte erwartet, dass test.test1 (a); und test.test2 (a) sollten beide kompilieren, wenn sie Referenzen weiterleiten, aber auch nicht.

Kann mir das jemand erklären? Vielen Dank!

bearbeiten -------------- Dank, Jungs ----------- Richard und Artemy korrekt sind.

+2

Ohne Bezug, ich weiß nicht, ob es traurig oder surreal ist, dass in der heutigen Zeit die VS2015 Toolchain 'void main()' akzeptiert. Ja wirklich ? – WhozCraig

+0

In Ihrem letzten geschlossenen Fall wird U nicht abgeleitet - Ihr Fall wird also nicht kompiliert. Um es ableitbar zu machen, nenne es test.test2 (a); und innen Test 2 ändern vorwärts , um vorwärts zu gehen

Antwort

2

Es ist eine gute Frage, die fast alle am Anfang füchtet.

template <class T> 
class A 
{ 
    template <class U> 
    void foo(T&& t, U&& u); 
}; 

In diesem Beispiel T nicht abgeleitet (es explizit definieren, wenn Sie die Vorlage instanziiert).

U wird abgeleitet, weil es von dem Argument u abgeleitet wird.

, daher in fast allen Fällen wäre es:

std::move(t); 
std::forward<U>(u); 
+0

BTW 'std :: vorwärts (t);' wäre äquivalent 'std :: move (t);' ist dieser Fall (aber weniger explizit). – Jarod42

2

sind beide T & & und U & & Forwarding Referenzen?

Nein, nur U&& ist eine Forwarding Referenz, weil U das einzige Template-Argument ist, die abgeleitet ist wird. T wurde bereits beim Instanziieren A "ausgewählt".

Verwandte Themen