Difference between quot;if constexpr()quot; Vs quot;if()quot;(“if constexpr()之间的区别与“if())
问题描述
if constexpr()
和 if()
有什么区别?
我可以在何时何地同时使用它们?
Where and When can I use both of them?
推荐答案
唯一的区别是 if constexpr
在编译时被评估,而 if
不是.这意味着分支可以在编译时被拒绝,因此永远不会被编译.
The only difference is that if constexpr
is evaluated at compile time, whereas if
is not. This means that branches can be rejected at compile time, and thus will never get compiled.
假设你有一个函数,length
,它返回一个数字的长度,或者一个具有 .length()
函数的类型的长度.你不能在一个函数中做到,编译器会抱怨:
Imagine you have a function, length
, that returns the length of a number, or the length of a type that has a .length()
function. You can't do it in one function, the compiler will complain:
template<typename T>
auto length(const T& value) noexcept {
if (std::integral<T>::value) { // is number
return value;
else
return value.length();
}
int main() noexcept {
int a = 5;
std::string b = "foo";
std::cout << length(a) << ' ' << length(b) << '
'; // doesn't compile
}
错误信息:
main.cpp: In instantiation of 'auto length(const T&) [with T = int]':
main.cpp:16:26: required from here
main.cpp:9:16: error: request for member 'length' in 'val', which is of non-class type 'const int'
return val.length();
~~~~^~~~~~
那是因为当编译器实例化length
时,函数会是这样的:
That's because when the compiler instantiates length
, the function will look like this:
auto length(const int& value) noexcept {
if (std::is_integral<int>::value) { // is number
return value;
else
return value.length();
}
value
是一个 int
,因此没有 length
成员函数,因此编译器会抱怨.编译器看不到 int
永远不会到达该语句,但这无关紧要,因为编译器无法保证.
value
is an int
, and as such doesn't have a length
member function, and so the compiler complains. The compiler can't see that statement will never be reached for an int
, but it doesn't matter, as the compiler can't guarantee that.
现在你可以特化 length
,但是对于很多类型(比如在这种情况下 - 每个数字和具有 length
成员函数的类),这会导致很多重复的代码.SFINAE 也是一个解决方案,但是它需要多个函数定义,这使得代码比下面需要的要长很多.
Now you can either specialize length
, but for a lot of types (like in this case - every number and class with a length
member function), this results in a lot of duplicated code. SFINAE is also a solution, but it requires multiple function definitions, which makes the code a lot longer than it needs to be compared to the below.
使用 if constexpr
而不是 if
意味着分支 (std::is_integral
) 将在编译时间,如果它是 true
,那么所有其他分支(else if
和 else
)都会被丢弃.如果是false
,则检查下一个分支(这里是else
),如果是true
,则丢弃所有其他分支,依此类推...
Using if constexpr
instead of if
means that the branch (std::is_integral<T>::value
) will get evaluated at compile time, and if it is true
then every other branch (else if
and else
) gets discarded. If it is false
, the next branch is checked (here else
), and if it is true
, discard every other branch, and so on...
template<typename T>
auto length(const T& value) noexcept {
if constexpr (std::integral<T>::value) { // is number
return value;
else
return value.length();
}
现在,当编译器实例化length
时,它看起来像这样:
Now, when the compiler will instantiate length
, it will look like this:
int length(const int& value) noexcept {
//if (std::is_integral<int>::value) { this branch is taken
return value;
//else discarded
// return value.length(); discarded
}
std::size_t length(const std::string& value) noexcept {
//if (std::is_integral<int>::value) { discarded
// return value; discarded
//else this branch is taken
return value.length();
}
所以这 2 个重载是有效的,代码将成功编译.
And so those 2 overloads are valid, and the code will compile successfully.
这篇关于“if constexpr()"之间的区别与“if()"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:“if constexpr()"之间的区别与“if()"


基础教程推荐
- 这个宏可以转换成函数吗? 2022-01-01
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
- 我有静态或动态 boost 库吗? 2021-01-01
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
- 在 C++ 中计算滚动/移动平均值 2021-01-01
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
- 常量变量在标题中不起作用 2021-01-01
- C++结构和函数声明。为什么它不能编译? 2022-11-07