2017-08-09 7 views
1

私はC#でのようなタイプのクエリを達成するために、このコードを使用しています: 最短のコードでconstexprを実行するにはどうすればバックポートできますか?

template<class T> 
constexpr bool IsSixtyFourBit() { 
    return is_same<T, int64_t>() || is_same<T, uint64_t>(); 
} 

template<class T> 
constexpr bool IsDouble() { 
    return is_same<T, double>() || is_same<T, double_t>(); 
} 

template<class T> 
constexpr bool IsFloat() { 
    return is_same<T, float>() || is_same<T, float_t>(); 
} 


template<class T> 
constexpr bool IsReal() { 
    return IsDouble<T>() || IsFloat<T>(); 
} 

template <class T> 
constexpr T MakePseudoNumberGenerator(T min, T max) { 
    if constexpr (IsSixtyFourBit<T>()) { 
     mt19937_64 rng(random_device{}());   // random-number engine used (Mersenne-Twister in this case) 
     uniform_int_distribution<T> uni(min, max); // guaranteed unbiased 

     return uni(rng); 
    } else if constexpr (IsReal<T>()) { 
     mt19937_64 rng(random_device{}());   // random-number engine used (Mersenne-Twister in this case) 
     uniform_real_distribution<T> uni(min, max); // guaranteed unbiased 

     return uni(rng); 
    } else { 
     mt19937 rng(random_device{}());   // random-number engine used (Mersenne-Twister in this case) 
     uniform_int_distribution<T> uni(min, max); // guaranteed unbiased 

     return uni(rng); 
    } 
} 

しかし、私は少なくともコードを使用してC++ 17の下にC++環境のためにそれをリライトする方法を見つけ出すことはできません...部分的な特殊ここでは動作しますが、それはその実用的な...

完全なコードではないはずです。私の理解でhttps://godbolt.org/g/QBs92V

+0

https://medium.com/@LoopPerfect/c-17-vs-c-14-if-constexpr-b518982bb1e2 私はまだ何を解読していますconstexprがフードの下でやっている場合... –

+0

あなたは* C++ 14 *でそれを書き直したいですか? –

+0

これをC++ 14で書き直すだけでなく、最短コードも書き直すことができます。 –

答えて

1

、少なくとも余分な機械や構文上の変更を必要とするif constexprをシミュレートする方法はstd::tupleを使用することです。

std::get<P ? 0 : 1>(std::forward_as_tuple(
    [&](auto) { T; }, 
    [&](auto) { F; }))(0); 

これは同じ順序で述語との両方のブランチを維持することができ:一般的なアプローチは、コード真と偽の枝を封入する2つの多型ラムダのいずれかへの呼び出しに

if constexpr (P) { 
    T; 
} else { 
    F; 
} 

を変換することです同じ囲み範囲実際には、ビジネスロジックを変更せずに、エミュレーションコードを__cplusplusのマクロチェックの内側に置くことは可能です。

ラムダは多型であるため、構文の正確性がチェックされ、Pが評価されるとインスタンス化されます。例えば

、あなたのケースで:

template <class T> 
constexpr T MakePseudoNumberGenerator(T min, T max) { 
    return std::get<IsSixtyFourBit<T>() ? 0 : 1>(std::forward_as_tuple(
    [&](auto) { 
     mt19937_64 rng(random_device{}());   // random-number engine used (Mersenne-Twister in this case) 
     uniform_int_distribution<T> uni(min, max); // guaranteed unbiased 

     return uni(rng); 
    }, std::get<IsReal<T>() ? 0 : 1>(std::forward_as_tuple(
    [&](auto) { 
     mt19937_64 rng(random_device{}());   // random-number engine used (Mersenne-Twister in this case) 
     uniform_real_distribution<T> uni(min, max); // guaranteed unbiased 

     return uni(rng); 
    }, 
    [&](auto) { 
     mt19937 rng(random_device{}());   // random-number engine used (Mersenne-Twister in this case) 
     uniform_int_distribution<T> uni(min, max); // guaranteed unbiased 

     return uni(rng); 
    }))))(0); 
} 
+0

それは本当に大きな考え方です。私は、条件付きのシミュレーションのためにタプルを使用することを知っていることはありません!感謝します! –

関連する問題