2015-03-05 12 views
6

Ho una classe template, qualcosa di simile:Come posso usare std :: chrono :: duration come parametro template?

template < typename T, size_t Seconds > class MyClass {} 

Ora, vorrei cambiare secondi per essere una durata, quindi la classe può essere parametrizzata con std::chrono::duration. Ad esempio, mi piacerebbe essere in grado di fare questo:

MyClass < std::string, std::chrono::seconds(30) > object; 

Inoltre, nel modello, vorrei specificare un valore predefinito, qualcosa come std::chrono::seconds(30).

+0

Si dovrebbe considerare di accettare la risposta qui sotto, sembra una risposta solida. –

risposta

11

È possibile progettare il modello in un modo intelligente:

template < typename T, typename Duration = std::chrono::seconds, int duration_value = 30 > 
class MyClass 
{ 
    // Now you can use duration here: 
    // auto duration = Duration(duration_value); 
}; 

E poi è possibile creare un'istanza il modello come

MyClass < std::string, std::chrono::seconds, 30 > object; 

Oppure, in realtà avere questi valori come valori predefiniti, semplicemente

MyClass <std::string> object; 

Modifica:

Tenendo conto richiesta PaperBirdMaster 's, è possibile limitare il tipo di modello Duration, per essere std::chrono::duration solo, in questo modo:

template <typename T> 
struct is_chrono_duration 
{ 
    static constexpr bool value = false; 
}; 

template <typename Rep, typename Period> 
struct is_chrono_duration<std::chrono::duration<Rep, Period>> 
{ 
    static constexpr bool value = true; 
}; 

template < typename T, typename Duration = std::chrono::seconds, int duration_value = 30 > 
class MyClass 
{ 
    static_assert(is_chrono_duration<Duration>::value, "duration must be a std::chrono::duration"); 
    // Now you can use duration here: 
    // auto duration = Duration(duration_value); 
}; 

int main(int argc, char ** argv) 
{ 
    MyClass < std::string, std::chrono::seconds, 1> obj1;  // Ok 
    MyClass < std::string, std::chrono::milliseconds, 1> obj2; // Ok 
    MyClass < std::string, int, 1> obj3;      // Error 
    return 0; 
} 
+1

Ciò consente di istanziare 'MyClass' con qualsiasi cosa che non sia un valore chrono, ad esempio:' MyClass ', è il comportamento previsto? Non dovrebbe essere meglio limitare il secondo parametro ai tipi di crono? –

+0

@PaperBirdMaster la tua logica può anche essere applicata ad esempio a 'std :: remove_if'. Cosa succede se qualcuno specifica qualcosa di inaspettato invece di 'UnaryPredicate p' se invece di iteratori? La risposta è semplice: non verrà compilata. – GreenScape

+1

non conosciamo la logica all'interno di 'MyClass', forse si compila con' double' o 'my_fancy_class' o wathever con gli operatori appropriati e non potrebbe essere il comportamento atteso ... comunque, la domanda riguardava la parametrizzazione del classe con 'std :: chrono :: duration' non con qualcosa che si comporta o assomiglia a' std :: chrono :: duration'. –

Problemi correlati