gpt4 book ai didi

c++ - "if constexpr()"与 "if()"之间的区别

转载 作者:IT老高 更新时间:2023-10-28 22:17:01 24 4
gpt4 key购买 nike

if constexpr()if() 有什么区别?

我可以在何时何地同时使用它们?

最佳答案

唯一的区别是 if constexpr在编译时评估,而 if不是。这意味着分支可以在编译时被拒绝,因此永远不会被编译。


假设你有一个函数,length ,它返回一个数字的长度,或具有 .length() 的类型的长度功能。你不能在一个函数中做到这一点,编译器会提示:

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) << '\n'; // 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 ,函数将如下所示:

auto length(const int& value) noexcept {
if (std::is_integral<int>::value) { // is number
return value;
else
return value.length();
}

valueint ,因此没有 length成员函数,因此编译器会提示。编译器看不到 int 永远不会到达该语句。 ,但没关系,因为编译器不能保证。

现在您可以专精 length ,但是对于很多类型(例如在这种情况下 - 每个数字和具有 length 成员函数的类),这会导致大量重复代码。 SFINAE也是一种解决方案,但是它需要多个函数定义,这使得代码比下面需要的要长很多。

使用 if constexpr而不是 if表示分支 ( std::is_integral<T>::value ) 将在编译时进行评估,如果是 true然后每个其他分支( else ifelse )都会被丢弃。如果是false ,检查下一个分支(这里是 else ),如果是 true ,丢弃所有其他分支,依此类推...

template<typename T>
auto length(const T& value) noexcept {
if constexpr (std::integral<T>::value) { // is number
return value;
else
return value.length();
}

现在,当编译器将实例化 length ,它看起来像这样:

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();
}

所以这两个重载是有效的,代码会编译成功。

关于c++ - "if constexpr()"与 "if()"之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43434491/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com