2016-07-23 7 views
0

erwarten Ich versuche, einige grundlegende C++ 11 zu lernen, Vortrag mit Scott Meyers auf youtube "Eine effektive C++ 14.11 Sampler" genanntstd :: vorwärts Visual Studio 13 nicht verhalten wie ich

https://www.youtube.com/watch?v=BezbcQIuCsY

seinen Beispielcode verwendet für std::forward (min 19 in der Vorlesung) ich den folgenden Code schrieb die Wirkung von std::forward

#include "stdafx.h" 
#include <string> 
#include <utility> 

class A 
{ 
public: 
    void Foo(std::string&& s) 
    { 
     std::string s2 = std::forward<std::string>(s); 
    } 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    A a; 

    std::string s3 = "Hello World"; 
    a.Foo(s3); 
    a.Foo("Hello World"); 

    return 0; 
} 

Überraschenderweise zu verstehen es nicht, kann nicht kompiliert a.Foo(s3) nicht implizit gegossen aus l Wert zu rvalue. So änderte ich a.Foo(s3); zu a.Foo(std::move(s3)); Nun kompiliert es. Allerdings wurde bei beiden Aufrufen von Foo std::forward<std::string>(s); ein rvalue aufgelöst und eine Move-Operation ausgeführt (s wurde auf "" zurückgesetzt, da sein Puffer gestohlen wurde).

Also ich verstehe wirklich nicht, was gut ist std::forward und wann es gilt. Was fehlt mir hier?

+0

'std :: string &&' ist eine rvalue Referenz, keine Forwarding Referenz (oder „universelle Referenz“, wie es für eine Weile bekannt war). – ildjarn

Antwort

2

Aufruf std::forward<> wenn Vorlage Argument Abzug/Referenz Kollabieren nicht beteiligt ist, macht keinen Sinn.

Der Punkt der Forwarding Referenzen (die Scott Meyers „universal Referenzen“ zu nennen pflegte) ist, dass in Abhängigkeit von der Wertkategorie von dem, was Sie erhalten,, Sie auch diesen Wert Kategorie weiterleiten kann.

Aber hier sind Sie überhaupt nicht verwirrt, was die Wertkategorie ist, es ist statisch.

Hier ist ein Kontext, die Vorlage Argument Abzug hat:

template<typename T> 
void f(T&& t) // T is to be deduced, && might be collapsed 
{ 
    g(std::forward<T>(t)); // will keep the category value 
} 

f(std::string{"hey"}); // T inferred std::string&&, so the parameter type is `std::string&& &&`, which is collapsed to `std::string &&`. 
0

Sie benötigen eine Forwarding-Referenz:

#include <string> 
#include <utility> 

class A 
{ 

public: 

    template <typename String> 
    void Foo(String&& s) 
    { 
     std::string s2 = std::forward<String>(s); 
    } 
}; 



int main() 
{ 
    A a; 

    std::string s3 = "Hello World"; 
    a.Foo(s3); 
    a.Foo("Hello World"); 

    return 0; 
} 

live example

Verwandte Themen