我使用以下代码来实现类似于C#中的类型查询:
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下使用最少的code...partial专门化为C++环境重写它,这应该是可行的,但它并不实用。
发布于 2017-08-09 18:15:04
在我的理解中,模拟if constexpr的方法是使用std::tuple,这种方法需要最少的额外机制和语法更改。一般的方法是翻译代码。
if constexpr (P) {
T;
} else {
F;
}调用封装了true和false分支的两个多态lambdas之一:
std::get<P ? 0 : 1>(std::forward_as_tuple(
[&](auto) { T; },
[&](auto) { F; }))(0);这允许将谓词和两个分支保持在相同的顺序和相同的封闭作用域中;实际上,可以将仿真代码放在检查__cplusplus版本的宏中,同时保持业务逻辑不变。
由于lambda是多态的,因此将检查它们的语法正确性,并且仅在评估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);
}https://stackoverflow.com/questions/45586847
复制相似问题