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
相关产品推荐
相关产品推荐

