2016-11-24 4 views
4

Betrachten Sie folgenden Code:std :: min std :: Chrono :: Dauer verschiedenen Typen

// durations are from std::chrono 
auto a = get_duration_1(); // milliseconds, will vary in future versions 
auto b = get_duration_2(); // seconds, will vary in future versions 
auto c = std::min(a, b); 

Es ist nicht kompiliert, da Compiler nicht korrekte Version von std::min wegen der unterschiedlichen Argumenttypen instanziieren.

Natürlich ist es jetzt möglich, explizit den Typ std::min<milliseconds> anzugeben. In zukünftigen Versionen dieses Codes werden die Typen variieren. Was ist der generische Weg, dies zu tun, ohne genaue Durationstypen zu kennen?

+0

Wenn es keine ist festgelegt und bestehende Spezialisierung von [ 'std :: min'] (http://en.cppreference.com/w/cpp/algorithm/ min) für ['std :: chrono :: duration'] (http://en.cppreference.com/w/cpp/chrono/duration) (und es gibt keine) dann gibt es kein generisches (und" nice ") Weg. Außer um eine solche Spezialisierung zu machen. Und wenn Sie es in mehr als nur ein paar Orten brauchen, dann könnte eine solche Spezialisierung eine gute Idee sein. –

+2

[Std :: min] (http://en.cppreference.com/w/cpp/algorithm/min) hat keine Version, die verschiedene Argumenttypen akzeptiert. Entweder eines der Argumente oder beides. –

+0

Ich ändere die Frage, so dass die Notwendigkeit für generischen Code explizit angezeigt wird. –

Antwort

8

Gegeben zwei Dauern, D1 d1 und D2 d2 ...

Sie beide Dauern ihrer gemeinsamen Typ konvertieren kann, und dann das Minimum dieser Werte finden.

Oder rufen Sie einfach std::min<std::common_type_t<D1, D2>>(d1, d2) an und lassen Sie sie bei Bedarf in diesen Typ konvertieren.

Dies funktioniert, weil std::common_type ist spezialisiert, um die richtige Sache für duration Typen zu tun, siehe [time.traits.specializations] in der C++ - Standard.

+1

Das kann in eine Funktionsvorlage eingepackt werden, oder? Nützliches Dienstprogramm, für mehr als nur 'std :: chrono' – StoryTeller

+0

Sieht wie eine Lösung aus. In diesem speziellen Fall mit 'auto' Variablen, sollte ich' std :: common_type '? –

+0

Ja, natürlich. In Ihrem Fall ist "D1" "declltype (a)" und "D2" ist "declltype (b)", also ersetzen Sie es entsprechend. Aber Vorsicht: das sollte 'common_type_t' nicht' common_type' sein. –

5

Sie können die folgende Funktion verwenden:

#include <chrono> 

template <typename T1, typename T2> 
auto generic_min(const T1& duration1, const T2& duration2) 
{ 
    using CommonType = typename std::common_type<T1,T2>::type; 
    const auto d1 = std::chrono::duration_cast<CommonType>(duration1); 
    const auto d2 = std::chrono::duration_cast<CommonType>(duration2); 
    return std::min(d1,d2); 
} 
+0

Leider kann ich nur eine Antwort als richtig markieren. Danke für den genauen Code! –

Verwandte Themen