`if constexpr` 可以用来声明不同类型和 init-expr 的变量吗
Can `if constexpr` be used to declare variables with different types and 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 语言中很常见,但我没有找到有关 C++17 的信息。
当然可以用
std::conditional<..., int, double>::type x;
但仅限于基本情况。即使是不同的初始化器(如上)也会造成大问题。
有两种方法行不通。
首先,变量被限制在它声明的范围内。省略大括号不会骗过编译器:int x = 5
仍然在它自己的范围内,并且在它出现后立即消失。
其次,if constexpr
的宽松语法规则仅适用于 if constexpr
的正文。允许在正文中创建的上下文泄漏到周围的范围是不可行的,因为根据定义它可能格式不正确,或者在 then/else 块之间不一致。 (如果 else 块将 x
声明为类型名怎么办?)
最重要的是,您需要将 bar()
移动到 if-body 或模板 foo()
本身,并让 x
的类型和值由您的 ...
.
此代码无法运行。问题是当您调用 bar
时 x
超出范围。但有一个解决方法:
constexpr auto t = []() -> auto {
if constexpr(/* condition */) return 1;
else return 2.9;
}();
bar(t);
稍微解释一下,它使用即时调用的 lambda 表达式以及自动 return 类型推导。因此,我们在适当的位置赋予 t 值,它不会超出范围。
当然,如果 if 语句不能在编译时求值,它就不会工作。如果你想在这个 lambda 内部做一些运行时操作,你不能将 t 作为 constexpr,但它仍然可以工作。
例如:
void foo()
{
if constexpr (...)
int x = 5;
else
double x = 10.0;
bar(x); // calls different overloads of bar with different values
}
在 D 语言中很常见,但我没有找到有关 C++17 的信息。
当然可以用
std::conditional<..., int, double>::type x;
但仅限于基本情况。即使是不同的初始化器(如上)也会造成大问题。
有两种方法行不通。
首先,变量被限制在它声明的范围内。省略大括号不会骗过编译器:int x = 5
仍然在它自己的范围内,并且在它出现后立即消失。
其次,if constexpr
的宽松语法规则仅适用于 if constexpr
的正文。允许在正文中创建的上下文泄漏到周围的范围是不可行的,因为根据定义它可能格式不正确,或者在 then/else 块之间不一致。 (如果 else 块将 x
声明为类型名怎么办?)
最重要的是,您需要将 bar()
移动到 if-body 或模板 foo()
本身,并让 x
的类型和值由您的 ...
.
此代码无法运行。问题是当您调用 bar
时 x
超出范围。但有一个解决方法:
constexpr auto t = []() -> auto {
if constexpr(/* condition */) return 1;
else return 2.9;
}();
bar(t);
稍微解释一下,它使用即时调用的 lambda 表达式以及自动 return 类型推导。因此,我们在适当的位置赋予 t 值,它不会超出范围。
当然,如果 if 语句不能在编译时求值,它就不会工作。如果你想在这个 lambda 内部做一些运行时操作,你不能将 t 作为 constexpr,但它仍然可以工作。