微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 min 仍然在 constexpr 内抱怨?

如何解决为什么 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>();
}

对于constexpr if

(强调我的)

如果 constexpr if 语句出现在模板化实体中,并且如果 实例化后条件不依赖于值,丢弃的 当封闭模板为 实例化。

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

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

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

来自cppreference

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

,

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

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

注意悬空引用。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。