2017-11-03 15 views
1

を私はSFINAE先はstdインスタンス化タイプを制限するために::クロノ::持続タイプ

template <typename T> 
class TemporalAlarmDelay<T, std::enable_if<std::is_base_of<std::chrono::duration< , >, T>::value, T>::type> 
{ 
public: 
    explicit TemporalAlarmDelay(T delay) 
     : mDelay(delay) 
    { 

    } 

private: 
    T mDelay; 
    std::chrono::steady_clock::time_point mTriggerTime; 
}; 


int main(int argc, char** args) 
{ 
    TemporalAlarmDelay<std::chrono::nanoseconds> nanosecondDelay; // this should work 
    TemporalAlarmDelay<std::chrono::milliseconds> millisecondDelay; // this should work 
    TemporalAlarmDelay<std::chrono::seconds> secondDelay;   // this should work 
    TemporalAlarmDelay<int> failDelay;        // fail to instantiate 
} 

意図はstd::chrono::durationの種類に制限することがある(例えばはstd::chrono::millisecondsstd::chrono::seconds)のような何かをしたいです。これについて最善の方法は何ですか?私の例では、std::is_base_ofを使用できると考えていましたが、ヘルパータイプ(例えばstd::chrono::millisecondsstd::chrono::secondsなど)は継承を使用しないことを認識しました。

+0

これは、ビットXY-問題のように聞こえます。あなたは何をしたいですか? – user0042

+0

いいえ、私は何をしたいのかを明確に述べています。私はどのようにインスタンス化したいかの例を提供します。助けていただきありがとうございます:) – tuskcode

答えて

1

そして、あなたの問題に非常に最も簡単な解決策のための...

#include <chrono> 

class TemporalAlarmDelay 
{ 
public: 
    explicit TemporalAlarmDelay(std::chrono::steady_clock::duration delay) 
     : mDelay(delay) 
    { 

    } 

private: 
    std::chrono::steady_clock::duration mDelay; 
    std::chrono::steady_clock::time_point mTriggerTime; 
}; 


int main() 
{ 
    using namespace std::chrono_literals; 
    TemporalAlarmDelay nanosecondDelay{1ns}; // this works 
    TemporalAlarmDelay millisecondDelay{1ms}; // this works 
    TemporalAlarmDelay secondDelay{1s};  // this works 
    TemporalAlarmDelay failDelay{1};   // compile-time error 
} 
+0

確かに単純なものです。単純なものは単純ではありませんでしたが、私は間違いなく実装を更新します。クロノとrts! – tuskcode

2

あなたはテンプレートの特殊使用することができます。代わりに、上記の最初の4行の

template <typename> class TemporalAlarmDelay; 

:Jarod42 @

template <typename T> 
class TemporalAlarmDelay 
{ 
    ~TemporalAlarmDelay() = delete; // prevent instantiation 
}; 

template <typename R, typename P> 
class TemporalAlarmDelay<std::chrono::duration<R, P>> 
{ 
    // your code 
}; 

はあなたがさえて逃げることを示唆しています。

+2

私は一般的な定義を省略します。 – Jarod42

+1

@ Jarod42:テンプレートを宣言するだけですか? 10年以上のC + +と私はこれを試みたことがない。良いアイデア。 –

2

あなたが作成することができます特徴:

template <typename T> struct is_chrono_duration : std::false_type {}; 

template <typename R, typename P> 
struct is_chrono_duration<std::chrono::duration<R, P>> : std::true_type {}; 

、その後:ベースJarod42のis_chrono_duration(も...正直に言うと、それをコピーする)、可能SFINAEからインスピレーションを取っ

template <typename T> 
class TemporalAlarmDelay 
{ 
    static_assert(is_chrono_duration<T>::value, "!"); 
    // your code 
}; 
+0

これは動作しませんでした:( 'C:\ IMC_System \ FastBuildDev \ PI.cpp(382):エラーC2440: '初期化中': 'TemporalAlarmDelay tuskcode

+0

@tuskcode - あなたのクラスが必要とするため、動作しません(コンストラクタはソースタイプを取ることができません)。 (例: '明示的なTemporalAlarmDelay(T delay = T {}):mDelay(delay())は、コンストラクタの引数ですが、この例では引数を0にします。 ) ')。) – max66

+0

そうです。有効な解決策がたくさんあります。 – tuskcode

0

(既定のブール値を超えて)ソリューション

template <typename T, bool = is_chrono_duration<T>::value> 
class TmpAlrD; 

template <typename T> 
class TmpAlrD<T, true> 
{ 
    // ... 
}; 

以下は完全なコンパイル用のexamplです電子

#include <chrono> 
#include <type_traits> 

template <typename> 
struct is_chrono_duration : std::false_type 
{ }; 

template <typename R, typename P> 
struct is_chrono_duration<std::chrono::duration<R, P>> : std::true_type 
{ }; 

template <typename T, bool = is_chrono_duration<T>::value> 
class TmpAlrD; 

template <typename T> 
class TmpAlrD<T, true> 
{ 
    public: 
     explicit TmpAlrD(T delay = T{}) : mDelay(delay) 
     { } 

    private: 
     T mDelay; 

     std::chrono::steady_clock::time_point mTriggerTime; 
}; 

int main() 
{ 
    TmpAlrD<std::chrono::nanoseconds> nsDelay; // compile 
    TmpAlrD<std::chrono::milliseconds> msDelay; // compile 
    TmpAlrD<std::chrono::seconds>  sDelay; // compile 
    //TemporalAlarmDelay<int>     // compilation error  
} 
関連する問題