如果 constexpr 使用尽可能短的代码,我该如何向后移植?
How do I backport if constexpr with the shortest code possible?
我正在使用此代码来实现类型查询,就像在 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 下C++的环境重写它......部分专业化应该在这里起作用,但它并不那么实用......
完整代码:https://godbolt.org/g/QBs92V
在我的理解中,模拟需要最少额外机械和语法更改的if constexpr
的方法是使用std::tuple
.一般方法是翻译代码
if constexpr (P) {
T;
} else {
F;
}
调用封装真分支和假分支的两个多态 lambda 之一:
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);
}
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 多成员Constexpr结构初始化
- 条件constexpr函数
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- Visual C++ constexpr Hints
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 为什么constexpr的性能比正常表达式差
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 为什么std::isnan 不是 constexpr?
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 更多constexpr容器是否需要mark_immutable_if_consexpr
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- constexpr上下文中std::initializer_list的验证
- constexpr构造函数需要常量成员函数时出现问题
- vs 2015 constexpr变量不恒定,但与2019相比还好吗
- C++constexpr实现差异
- 如果 constexpr 使用尽可能短的代码,我该如何向后移植?