You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中无变量类型的decltype使用咨询及项目代码说明

关于C++中decltype不依赖变量的正确用法

嘿,我来帮你把decltype的这个用法理清楚~首先先看你代码里的decltype(A().u),其实这里有个容易误解的点:decltype的操作数是未求值的,也就是说A()并不会真的构造一个临时对象,所以你代码里的Called只会输出一次(来自a2的构造),这点不用担心。不过这个写法有局限性——如果A没有默认构造函数(比如构造函数被删除、私有,或者需要传入参数),A()就会编译失败。

那要做到完全不依赖变量实例,同时适配所有类的情况,咱们可以用std::declval,它在<utility>头文件里,专门用来在未求值上下文中生成指定类型的引用,不需要构造对象。

推荐的写法

把你代码里的decltype(A().u)改成:

decltype(std::declval<A>().u) p;

这样不管A能不能默认构造,都能正确获取A::u的类型,而且完全不依赖任何已存在的变量,直接从类类型出发。

其他不依赖变量的decltype用法

除了类成员类型,还有几种常见场景:

  • 获取函数返回值类型:如果想知道my_func(int, std::string)的返回类型,不用调用函数,直接写:
    decltype(my_func(std::declval<int>(), std::declval<std::string>())) return_type;
    
  • 通过成员指针获取类型:如果习惯用成员指针的方式,也可以这么写(和第一种效果一致,只是写法稍繁琐):
    #include <type_traits> // 需要这个头文件用std::remove_pointer_t
    std::remove_pointer_t<decltype(&A::u)> p;
    

修改后的完整代码示例

#include <iostream>
#include <inttypes.h>
#include <utility> // 引入std::declval

#define SA(obj) ((obj)->u)
struct A {
    A() { std::cout << "Called" << std::flush << std::endl; }
    uint32_t u;
};
int main() {
    struct A a2;
    // 通用方式获取A::u的类型,无需构造临时对象,适配所有类
    decltype(std::declval<A>().u) p;
    a2.u = 99;
    p = a2.u;
    if(a2.u != SA(&a2) )
        std::cout << "Not Same" << std::flush << std::endl;
    else
        std::cout << "Same" << std::flush << std::endl;
    return 0;
}

这样写既满足了不依赖变量的需求,又比原来的写法更通用,不会因为类的构造函数限制而报错~

内容的提问来源于stack exchange,提问作者Programmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:50:17