为什么 min 仍然在 constexpr 中抱怨?
Why does min still complain inside constexpr?
我有以下代码片段:
#include <iostream>
#include <type_traits>
#include <algorithm>
#include <cstdint>
using T = double;
int main()
{
f();
}
void f() {
T x = 2;
if constexpr(std::is_integral_v<T>)
{
std::cout << std::min(static_cast<int64_t>(2), x);
} else {
std::cout << std::min(1.0, x);
}
}
编译器正在解释
<source>:15:57: error: no matching function for call to 'min(int64_t, T&)'
我认为这不会有问题,因为当 T 是双精度时,不会实例化第一个分支。显然我的理解是错误的。谁能帮忙指出我的理解哪里不对?
std::min
与引用一起使用。并且两个参数应该是相同的类型。由于您提供了 2 种不同的类型,因此它无法决定参数类型应该是哪一种。你可以通过显式指定你喜欢的类型来解决这个问题,这两个参数都被转换:
std::min<double>(static_cast<int64_t>(2), x)
小心悬挂引用。
if constexpr
的失败分支无关紧要的情况仅在模板中,而 f
不是模板函数。
您需要制作 f()
模板和 T
模板参数。
template <typename T>
void f() {
T x = 2;
if constexpr(std::is_integral_v<T>)
{
std::cout << std::min(static_cast<int64_t>(2), x);
} else {
std::cout << std::min(1.0, x);
}
}
然后
int main()
{
f<double>();
}
对于constexpr if:
(强调我的)
If a constexpr if statement appears inside a templated entity, and if
condition is not value-dependent after instantiation, the discarded
statement is not instantiated when the enclosing template is
instantiated .
Outside a template, a discarded statement is fully checked. if constexpr
is not a substitute for the #if
preprocessing directive:
void f() {
if constexpr(false) {
int i = 0;
int *p = i; // Error even though in discarded statement
}
}
在模板之外,constexpr if
子句的“假”分支被丢弃,未被忽略。因此,这样一个分支中的代码必须仍然是格式良好的(而你的不是,因为给定的原因)。
来自cppreference:
Outside a template, a discarded statement is fully checked. if constexpr
is not a substitute for the #if preprocessing directive.
我有以下代码片段:
#include <iostream>
#include <type_traits>
#include <algorithm>
#include <cstdint>
using T = double;
int main()
{
f();
}
void f() {
T x = 2;
if constexpr(std::is_integral_v<T>)
{
std::cout << std::min(static_cast<int64_t>(2), x);
} else {
std::cout << std::min(1.0, x);
}
}
编译器正在解释
<source>:15:57: error: no matching function for call to 'min(int64_t, T&)'
我认为这不会有问题,因为当 T 是双精度时,不会实例化第一个分支。显然我的理解是错误的。谁能帮忙指出我的理解哪里不对?
std::min
与引用一起使用。并且两个参数应该是相同的类型。由于您提供了 2 种不同的类型,因此它无法决定参数类型应该是哪一种。你可以通过显式指定你喜欢的类型来解决这个问题,这两个参数都被转换:
std::min<double>(static_cast<int64_t>(2), x)
小心悬挂引用。
if constexpr
的失败分支无关紧要的情况仅在模板中,而 f
不是模板函数。
您需要制作 f()
模板和 T
模板参数。
template <typename T>
void f() {
T x = 2;
if constexpr(std::is_integral_v<T>)
{
std::cout << std::min(static_cast<int64_t>(2), x);
} else {
std::cout << std::min(1.0, x);
}
}
然后
int main()
{
f<double>();
}
对于constexpr if:
(强调我的)
If a constexpr if statement appears inside a templated entity, and if condition is not value-dependent after instantiation, the discarded statement is not instantiated when the enclosing template is instantiated .
Outside a template, a discarded statement is fully checked.
if constexpr
is not a substitute for the#if
preprocessing directive:void f() { if constexpr(false) { int i = 0; int *p = i; // Error even though in discarded statement } }
在模板之外,constexpr if
子句的“假”分支被丢弃,未被忽略。因此,这样一个分支中的代码必须仍然是格式良好的(而你的不是,因为给定的原因)。
来自cppreference:
Outside a template, a discarded statement is fully checked.
if constexpr
is not a substitute for the #if preprocessing directive.