if constexpr()
和if()
之间有什么区别?我可以在哪里和什么时候使用它们?
if constexpr()
和if()
之间有什么区别?if constexpr
在编译时评估,而if
不会。这意味着分支可以在编译时被拒绝,因此永远不会被编译。
length
,它返回一个数字的长度,或者返回一个具有.length()
函数的类型的长度。你不能在一个函数中完成这个任务,否则编译器会报错:template<typename T>
auto length(const T& value) noexcept {
if (std::is_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();
}
value
是一个 int
,因此没有 length
成员函数,所以编译器报错。编译器无法看到对于一个 int
,该语句永远不会被执行,但无论如何,编译器无法保证。
现在你可以专门为 length
进行特化,但对于许多类型(比如在这种情况下 - 每个具有 length
成员函数的数字和类),这会导致大量重复的代码。SFINAE 也是一种解决方案,但它需要多个函数定义,这使得代码比下面的方式冗长得多。
使用 if constexpr
而不是 if
意味着分支(std::is_integral<T>::value
)将在编译时评估,并且如果为 true
,则会丢弃其他所有分支(else if
和 else
)。如果为 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 constexpr (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 constexpr (std::is_integral<int>::value) { discarded
// return value; discarded
//else this branch is taken
return value.length();
}
所以这两个重载是有效的,代码会成功编译。
if constexpr
,您可以调用一个模板结构体,并(部分)特化它以避免代码重复。因此,在我看来,if constexpr
的主要好处是更符合程序员的“自然”外观。 - Daniel Jourtrue
,那么其他分支(else if
和else
)都会被丢弃。”)。 - dfribif (std::integral<T>::value) { // is number
应该在开头改为 std::is_integral<T>::value
- user3882729普通的if
语句:
if constexpr
语句:
if constexpr
语句,它应该已经拥有足够的信息来评估条件。唯一的例外是当这个语句出现在一个模板中时,在这种情况下可能没有足够的信息,直到模板参数被指定。常量表达式不能依赖于普通函数参数,因为它们的值在编译时不可知。 - Brian Biif ... else if ... else ...
,那么实际上有两个if语句,一个嵌套在另一个中,每个语句都有两个子语句。 - Brian Biif
呢?编译器可以决定它是 if constexpr
还是普通的 if
。因此,这个东西不会影响程序员,但规范必须改变:如果一个 if
条件在编译时评估,则只编译 if
或 else
代码。但对于程序员来说,这是透明的。只是好奇。 - Chameleon
if constexpr
是新语法,而不是无效的constexpr if
。 - Rakete1111