C++中的decltype、std::declval 和 std::decay_t傻傻分不清楚

本文介绍了C++标准库中的类型相关工具decltype、declval和decay_t。decltype用于从表达式推导类型,可用于推导函数返回类型等;declval用于不实际调用构造函数生成对象引用;decay_t用于返回给定类型“衰变”后的类型,去除多余限定符,使函数模板匹配更精确。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在C++中提到推导第一个映入脑海的可能是“模板”,当然有人也可能想到 auto,这些都是和推导相关的语言语法,再比如“完美转发”等等,总是就是他们的类型不用明明白白的写出来,可以利用一种简单的方式来定义,比如 candidates 是一个字符串数组, 如果遍历它我们可以写成 for (auto& skillId : candidates),而不用将 skillId 变量定义成 const std::string&,这在一定程度上带来了便利,今天的几个东东也是用于推导的,我们一起来看看。

它们是什么

decltypestd::declvalstd::decay_t 都是 C++ 标准库中的类型相关工具,这些工具在 C++ 编程中提供了强大的类型推导和处理能力,使得代码更加灵活。

  • decltype 是一个关键字,用于从一个表达式中推导出其类型。它通常与表达式一起使用,以便在编译时确定表达式的类型。例如:

    int x = 5;
    decltype(x) y = 10;  // y 的类型将被推导为 int
    

    decltype 还可以用于推导函数返回类型,以及在泛型编程中处理模板的类型。

  • std::declval 是一个函数模板,用于在不实际调用构造函数的情况下生成一个对象引用,以便在类型推导中使用。通常在需要引用某个类型的对象但实际无法创建该对象的上下文中使用,例如在函数返回类型推导中:

    template <typename T>
    auto createAndProcess() -> decltype(std::declval<T>().process()) {
        // 此处只是用于类型推导,并不会实际创建 T 的对象
    }
    

    在这个例子中,std::declval<T>().process() 用于推导函数的返回类型,但并不会实际调用 process 函数。

  • std::decay_t 是一个类型转换工具模板,用于将给定类型的"衰变"后的类型返回。衰变指的是将类型转换为其"自然"形式,即去掉引用、添加 cv 限定符(const 和 volatile)。例如:

    using T1 = std::decay_t<int&>;      // T1 为 int
    using T2 = std::decay_t<const int>; // T2 为 int
    using T3 = std::decay_t<int[]>;     // T3 为 int*
    

    std::decay_t 在模板编程中很有用,因为它可以帮助去除类型的多余限定符,使得函数模板的匹配更加精确。

通俗解释

如果看了上面的例子还是有点迷糊,那我再解释的通俗一点:

  • decltype 读音为 “dee-kluh-type”,就是返回一个变量的类型,比如你有一个对象 obj 想要再定义一个和它相同各类型的变量就可以写成 decltype(obj) newObj;

  • std::declval 读音为 “standard dee-cl-val”,它能返回类型 T 的右值引用,其实是一个伪实例,不会产生任何临时对象,也不会因为表达式很复杂而发生真实的计算。因为不会真正的进行构造,所以可以实现在元编程时伪构造一个没有定义默认构造函数类,还可以避开纯虚基类不能实例化的问题,说白了它就是假装创建个对象用于推导类型。

  • std::decay_t 读音为 “standard dee-kay tee”,有点褪去外表直击内心的意味,就是大家一起褪去花里胡哨的修饰符,获得原始的类型,用于函数模板的匹配更加精确,比如判断类型 T 是不是int,if constexpr (std::is_same_v<std::decay_t<T>, int>)

总结

  • decltype 是关键字,用于有了值或对象求类型的
  • std::declval 是函数模板,用于伪造一个对象但不实际构造的
  • std::decay_t 是类模板,用于去除修饰符获取原始类型的
  • 没想到decltype 居然是关键字,结果一查发现C++的关键字已经膨胀了,下次总结一下
==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==

当身边出现不和谐声音的时候问问自己,是不是你把他们招来的,用实力让他们闭嘴,而不要视图通过语言让他们明白

### ROC 曲线概述 ROC曲线(受试者工作特征曲线)是一种广泛应用于二值分类器性能评估的图形化表示方法[^1]。该曲线通过描绘真阳性率(True Positive Rate, TPR),也称为敏感度或召回率,与假阳性率(False Positive Rate, FPR)之间的关系来展示不同阈值下的模型表现。 #### 真阳性假阳性率计算方式 对于给定的一个概率预测模型,在不同的决策边界下可以得到一系列混淆矩阵。基于此,TPR FPR 的定义如下: - **真阳性率 (TPR)** 或 召回率 = TP / (TP + FN),其中 TP 表示真正例数,FN 是指假反例数。 - **假阳性率 (FPR)** = FP / (FP + TN),这里 FP 指的是假正例数量,TN 则代表真实负例的数量。 ```python from sklearn.metrics import roc_curve, auc import matplotlib.pyplot as plt def plot_roc(y_true, y_scores): fpr, tpr, _ = roc_curve(y_true, y_scores) roc_auc = auc(fpr, tpr) plt.figure() lw = 2 plt.plot(fpr, tpr, color='darkorange', lw=lw, label=f'ROC curve (area = {roc_auc:.2f})') plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--') plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('Receiver Operating Characteristic Curve') plt.legend(loc="lower right") plt.show() # 假设我们有一个真实的标签列表对应的分数/概率估计 plot_roc([0, 1, 1, 0, 1], [0.1, 0.4, 0.35, 0.8, 0.7]) ``` #### AUC 度量标准 AUC即曲线下面积(Area Under the Curve), 它衡量了整个二维空间内的积分区域大小。理想情况下,当分类器完美区分两类数据时,其AUC等于1;而随机猜测的结果对应于一条斜率为1的直线,此时AUC=0.5。因此,较高的AUC意味着更好的分类能力[^2]。 #### 使用场景考量 尽管ROC曲线提供了全面的理解视角,但在某些特定条件下可能不如其他类型的图表实用。例如,在处理高度不平衡的数据集时,精确率-召回率(Precision-Recall)图可能会提供更直观的信息[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlbertS

常来“玩”啊~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值