三元运算符和 if constexpr
Ternary operator and if constexpr
我有时根据某些bool
调用 2 个返回不同类型的constexpr
函数并将其分配给常量auto
。
不幸的是,三元运算符需要类型是"相似"的。
我在下面的代码中有解决方法,但它非常冗长。有没有更好的方法?
#include <iostream>
#include <string>
constexpr int get_int(){
return 47;
}
constexpr std::string_view get_string(){
return "47";
}
constexpr bool use_str = false;
constexpr auto get_dispatch(){
if constexpr(use_str){
return get_string();
} else{
return get_int();
}
}
int main()
{
// what I want : constexpr auto val = use_str ? get_string():get_int();
// what works:
constexpr auto val = get_dispatch();
std::cout << val << std::endl;
}
另一种选择是使用标记调度:
constexpr int get(std::false_type) {
return 47;
}
constexpr std::string_view get(std::true_type) {
return "47";
}
int main() {
constexpr auto val = get(std::bool_constant<use_str>{});
std::cout << val << std::endl;
}
不确定它更好,但有了std::variant
:
int main()
{
using my_variant = std::variant<int, std::string_view>;
constexpr auto val = use_str ? my_variant{get_string()} : my_variant{get_int()};
std::visit([](const auto& v) {std::cout << v << std::endl;}, val);
}
演示
这应该有效:
template <bool>
struct value_chooser;
template<>
struct value_chooser<true>
{
static constexpr auto value = "47";
};
template<>
struct value_chooser<false>
{
static constexpr auto value = 47;
};
int main()
{
auto value1 = value_chooser<true>::value;
auto value2 = value_chooser<false>::value;
}
现场示例
我在下面的代码中有解决方法,但它非常冗长。有没有更好的方法?
使用 C++17,您可以使用if constexpr
在我看来这是一个很好的解决方案。
如果你真的想要一些不同的东西,我提出了一种基于模板功能完全专业化的方法(Evg 和 Slava 解决方案之间的混合(
我的意思是
#include <iostream>
#include <string>
template <bool>
constexpr auto get_value ()
{ return 47; }
template <>
constexpr auto get_value<true> ()
{ return std::string_view{"47"}; }
int main()
{
constexpr auto use_str = false;
constexpr auto val = get_value<use_str>();
std::cout << val << std::endl;
}
正如 Slava 所指出的,具有默认版本和针对一种情况的显式专用化的模板函数可能不太易读。
因此,如果您更喜欢更冗长但更具可读性的变体,您可以为get_value()
编写两个显式专用化,如下所示
template <bool>
constexpr auto get_value ();
template <>
constexpr auto get_value<false> ()
{ return 47; }
template <>
constexpr auto get_value<true> ()
{ return std::string_view{"47"}; }
相关文章:
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 三元运算符和 if constexpr
- C++20. is_constant_evaluated() vs if constexpr
- LLVM覆盖被if-constexpr混淆了
- 在if constexpr中使用带参数包的概念时,升级到gcc 9后出现编译错误
- 是否可以使用"if constexpr"来声明具有不同类型和init-expr的变量
- 对'if constexpr'的错误理解
- 从语言设计层面来看,当编译时无法推断条件时,为什么"if constexpr"不衰减到"trival if"
- 如何让编译器忽略这个计算结果为 false 的 if-constexpr?
- 无法编译包含"if constexpr"的函数模板实例化
- 从“if constexpr”分支扩展对象生存期/范围
- MSVC 和 clang for if constexpr 分支的不同行为
- 禁用具有"if constexpr"和 SFINAE 的分支
- 'if constexpr branch'不会在模板函数内的 lambda 中被丢弃
- 斐波那契和'if constexpr'
- 从编译器优化和代码性能的角度来看,"if constexpr"与"if"
- if constexpr的False分支未在模板化lambda中丢弃
- 在“if constexpr”块中声明的变量的范围
- 编译器之间在丢弃的 if constexpr(false) 语句中实例化模板的行为不一致