2017-07-04 2 views
0

Ich kann das folgende Programm nicht kompilieren.Warum std :: move funktioniert nicht mit std :: list

void toSin(std::list<double>&& list) 
{ 
    std::for_each(list.begin(), list.end(), [](double& x) 
    { 
     x = sin(x); 
    }); 
} 

int main() 
{ 
    std::list<double> list; 
    const double pi = 3.141592; 
    const double epsilon = 0.0000001; 
    for (double x = 0.0; x < 2 * pi + epsilon; x = x + pi/16) 
    { 
     list.push_back(x); 
    } 
    // Start thread 
    std::thread th(toSin, std::move(list)); 
    th.join(); 
    return 0; 
} 

ich> Fehler C2664: 'void (std::list<double,std::allocator<_Ty>> &&)': Konvertierung Argument 1 von 'std::list<double,std::allocator<_Ty>>' auf 'std::list<double,std::allocator<_Ty>> &&'

+0

Reproduzieren kann ich nicht . Welche Version von Visual Studio verwenden Sie? Wohlgemerkt, ich habe ein paar fehlende Header hinzugefügt. – user4581301

+3

Die Zeile 'std :: thread th (toSin, std :: move (list));' impliziert, dass Sie nicht über 'list' hinauslaufen sollten, da dieser weggerückt ist. Aber Sie versuchen, in der nächsten Zeile darüber zu iterieren. –

+0

Visual Studio 2013 –

Antwort

0

Ich fühle mich wie Ihr Compiler ist hier falsch. Ein verfallener (kopierter) Werttyp sollte an eine rvalue-Referenz gebunden werden können.

nehmen jeden Fall einen Blick auf this quote from the documentation

3) Erstellt neue std :: Thread-Objekt und verbindet sie mit einem Ausführungs-Thread. Der neue Thread der Ausführung beginnt

std::invoke(decay_copy(std::forward<Function>(f)), decay_copy(std::forward<Args>(args))...); 

Im Grunde alles, was man als Argument an den Konstruktor std::thread passiert Ausführung wird als Funktion Argument an die Funktion kopiert werden.

Auch wissen, dass Ihre Funktion wird gut funktionieren, wenn Sie es die std::list Variable nach Wert anstelle von Rvalue-Referenz akzeptieren. Siehe Correct usage of rvalue references as parameters für mehr


Wenn Ihre Absicht einen Verweis auf eine Variable auf eine Thread-Funktion zu übergeben ist, so wie ich es tun in der Regel mit einem Lambda ist

std::list<double> lst; 
auto th = std::thread{[&lst]() { 
    toSin(lst); 
}}; 

Aber auch std::ref verwenden können für den gleichen Effekt. Ich persönlich finde nur, dass der Lambda-Ansatz klarer ist.

std::list<double> lst; 
auto th = std::thread{toSin, std::ref(lst)}; 

Also as correctly pointed out in the comments, haben Sie eine Race-Bedingung in Ihrem Code, den Sie mit einem mutex, oder warten Sie auf den Faden verhindern sollte

auto th = std::thread{[&lst]() { 
    toSin(lst); 
}}; 
th.join(); 

// then iterate and print out 
+0

Der obige Code wurde aktualisiert. Ich wollte nur einen eindeutigen Speicher für den Worker-Thread haben, um Synchronisationsprobleme zu vermeiden. –

+0

@NARESHKITTUR Wenn Sie das tun, wie wollen Sie die Liste später im Hauptthread ausdrucken? – Curious

+0

True, ich kann die Liste im Hauptthread nicht verwenden. Ich muss die Liste im Worker-Thread selbst bearbeiten/drucken. Um dieses Problem zu umgehen, sollte ich die Liste als Referenz mit dem Mutex übergeben. –

0

Ich denke, zu beenden, dass Sie vielleicht einige verpassen #include funktioniert dieser Code auf Visual Studio 2015

#include <algorithm> 
#include <list> 
#include <thread> 
void toSin(std::list<double>&& list) 
{ 
    std::for_each(list.begin(), list.end(), [](double& x) 
    { 
     x = sin(x); 
    }); 
} 

int main() 
{ 
    std::list<double> list; 
    const double pi = 3.141592; 
    const double epsilon = 0.0000001; 
    for (double x = 0.0; x < 2 * pi + epsilon; x = x + pi/16) 
    { 
     list.push_back(x); 
    } 
    // Start thread 
    std::thread th(toSin, std::move(list)); 
    th.join(); 
    return 0; 
} 
+0

beenden Visual Studio 2015 ist nicht Visual Studio 2013. 2013 hat klaffende Löcher in seiner C++ 11-Unterstützung. Quoten sind gut, dass es nicht kompiliert. Ich habe keinen leichten Zugang zu 2013, konnte den Punkt des Upgrades nicht sehen, bis die Löcher gefüllt waren, also habe ich keine Kopie, um es auszuprobieren. – user4581301

Verwandte Themen