为什么min还在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是双精度体时,第一个分支不会被实例化。显然我的理解是错误的。有人能帮我指出我的理解哪里出错了吗?

需要制作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>();
}

For constexpr:

(强调我的)

如果constexpr If语句出现在模板实体中,并且如果条件在实例化后不依赖于值,则丢弃语句未在封装模板实例化时实例化实例化。

在模板外部,完全检查丢弃的语句。if constexpr不能代替#if预处理指令:

void f() {
if constexpr(false) {
int i = 0;
int *p = i; // Error even though in discarded statement
}
}

在模板外,constexpr if子句的分支被丢弃不被忽略。因此,这样一个分支中的代码必须仍然是格式良好的(而您的代码不是,因为给出的原因)。

从cppreference:

在模板外部,完全检查丢弃的语句。if constexpr不能代替#if预处理指令。

std::min适用于引用。两个参数应该是相同的类型。由于您提供了两种不同的类型,它无法决定参数类型应该是哪一种。您可以通过显式指定要转换的两个参数的类型来解决这个问题:

std::min<double>(static_cast<int64_t>(2), x)

注意悬空引用

if constexpr的失败分支无关紧要的情况只存在于模板中,且f不是模板函数。

最新更新