是否可以使用"if constexpr"来声明具有不同类型和init-expr的变量



例如:

void foo()
{
if constexpr (...)
int x = 5;
else
double x = 10.0;
bar(x); // calls different overloads of bar with different values
}

这在 D lang 中很常见,但我没有找到有关 C++17 的信息。

当然,可以使用类似的东西

std::conditional<..., int, double>::type x;

但仅限于基本情况。即使是不同的初始化器(如上所述(也会产生大问题。

这段代码不可能工作。问题是当您调用xbar超出了范围。但是有一个解决方法:

constexpr auto t = []() -> auto {
if constexpr(/* condition */) return 1;
else return 2.9;
}();
bar(t);

为了解释一点,它使用即时调用的 lambda 表达式以及自动返回类型推导。因此,我们就地给出 t 值,它不会超出范围。

当然,如果在编译时无法计算 if 语句,则它不起作用。如果你想在这个lambda中做一些运行时操作,你不能将t作为constexpr,但它仍然可以工作。

有两种方法不起作用。

首先,变量仅限于声明它的作用域。省略大括号不会愚弄编译器:int x = 5仍然在自己的范围内,并且在出现后立即消失。

其次,if constexpr宽松的语法规则只适用于if constexpr的身体。允许在正文中创建的上下文泄漏到周围范围是不可行的,因为根据定义,它可能格式不正确,或者在 then/else 块之间不一致。(如果 else-block 声明x为类型名怎么办?

最重要的是,您需要将bar()移动到 if 正文或模板本身foo(),并让x的类型和值由您的...确定。