2013-04-25 5 views
15

Ich verstehe nicht, warum dieser Code mit g ++ Drosseln 4.7.2:Der Unterschied zwischen zwei time_point-Instanzen ist keine Dauer?

#include <chrono> 

main() 
{ 
    std::chrono::system_clock::time_point t1, t2 ; 
    std::chrono::seconds delay ; 

    t1 = std::chrono::system_clock::time_point::max() ; 
    t2 = std::chrono::system_clock::now() ; 
    delay = t1 - t2 ; 
    // t1 = t2 + delay ; 
    // t1 = t2 - delay ; 
} 

mit dem Fehler:

test.cc: In function ‘int main()’: 
test.cc:10:18: error: no match for ‘operator=’ in ‘delay = std::chrono::operator,<std::chrono::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000l> >, std::chrono::duration<long int, std::ratio<1l, 1000000l> > >((*(const std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000l> > >*)(& t1)), (*(const std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000l> > >*)(& t2)))’ 

Es schien mir, dass "time_point - time_point" gibt eine "Dauer" .

+4

Oh ja, richtig, C++ Compiler ** noch ** saugen bei Fehlermeldungen. –

+0

@KonradRudolph-Bibliotheksautoren konnten sie mit liberalerer 'static_assert'-Verwendung erheblich verbessern, ich bin mir nicht sicher, warum sie das nicht tun. –

+0

@DavidBrown: Sie können 'static_assert' nicht verwenden, um zu melden, ob eine geeignete Funktion/Operatorüberladung existiert. Konzepte könnten helfen, aber sie existieren noch nicht. –

Antwort

19

Es produziert eine Dauer, aber es gibt verschiedene Arten von Dauern. std::chrono::duration wird auf eine Darstellungsart und ein Einheitenverhältnis templatisiert. std::chrono::seconds hat zum Beispiel ein Einheitenverhältnis von 1, während std::chono::nanoseconds ein Einheitenverhältnis von std::nano oder 1/1000000000 hat. Zeitpunkte haben dieselben Template-Parameter.

Das spezifische Einheitsverhältnis von std::chrono::system_clock::time_point ist Implementierung definiert, aber es ist fast sicher weniger als das von std::chrono::seconds. Somit hat die Dauer, die durch Subtrahieren dieser zwei Zeitpunkte erzeugt wird, eine viel höhere Genauigkeit, als durch std::chrono::seconds dargestellt werden kann. Das Standardverhalten besteht darin, Zuordnungen nicht zuzulassen, die die Genauigkeit mit Dauer verlieren, die Integer-Darstellungen haben. Sie können also entweder eine Dauer mit ausreichender Genauigkeit verwenden (std::chrono::system_clock::duration) oder das Ergebnis auf die von Ihnen gewünschte Dauer umwandeln (std::chrono::duration_cast<std::chrono::seconds>(...)).

+0

Vielen Dank für Ihre Antwort. Also, wenn ich den std :: chrono :: nanoseconds-Typ für die Verzögerungsvariable verwendet hätte, hätte ich das Problem nicht bemerkt, und ich hätte nichts Wichtiges gelernt! – pdagog

+0

@pdagog 'std :: chrono :: nanoseconds' wird nicht unbedingt funktionieren (zumindest nicht überall). 'std :: chrono :: system_clock :: time_point' könnte in Nanosekunden sein, oder es könnte etwas kleiner sein. Deshalb sollten Sie 'std :: chrono :: system_clock :: duration' verwenden. –

+0

Sure: Ich hätte sagen sollen "Also, wenn ich den std :: chrono :: nanoseconds-Typ für die Verzögerungsvariable verwendet hätte, was scheint, dass die Uhr Korn auf meinem System ist, hätte ich nicht bemerkt ...". Danke für die Präzision. – pdagog

3

time_point - time_point gibt eine duration zurück, nur nicht die im Code. Sie könnten std::chrono::seconds durch std::chrono::system_clock::duration ersetzen, oder Sie könnten einen duration_cast verwenden, um zu der Art zu konvertieren, die Sie benötigen.

1

Der Unterschied zwischen zwei Zeitpunkten ist in der Tat eine Dauer; aber Sie können nicht implizit einen Durationstyp in einen anderen konvertieren, da dies die Genauigkeit im Hintergrund verlieren könnte.

Wenn Sie die Präzision system_clock::duration-seconds reduzieren wollen, dann müssen Sie die Umwandlung explizit machen mit einem duration_cast:

delay = duration_cast<std::chrono::seconds>(t1 - t2); 

Alternativ könnten Sie die Genauigkeit der Systemuhr behalten:

auto delay = t1 - t2; // Probably microseconds, or nanoseconds, or something 
Verwandte Themen