C++11中如何在成员变量后定义时使用decltype编写成员函数?
问题描述
如何让以下代码片段在C++11环境下编译通过,且无需将成员变量定义在成员函数之前?把成员变量写在成员函数之前显得很不美观。
原报错代码:
#include <vector> class Demo { public: decltype(m_data) foo(){ return m_data; }; private: std::vector<int> m_data; }; int main() { Demo demo; auto data = demo.foo(); return 0; }
注:C++14中可通过分离成员函数声明与定义的方式正常运行,代码如下:
#include <vector> class Demo { public: decltype(auto) foo(); private: std::vector<int> m_data; }; decltype(auto) Demo::foo() { return m_data; } int main() { Demo demo; auto data = demo.foo(); return 0; }
解决方案
针对C++11的特性限制,提供三种可行方案:
方案1:后置返回类型 + this指针
利用C++11的后置返回类型特性,此时->后的表达式处于类的完整作用域内,可通过this->m_data引用后续定义的成员变量:
#include <vector> class Demo { public: auto foo() -> decltype(this->m_data) { return m_data; }; private: std::vector<int> m_data; }; int main() { Demo demo; auto data = demo.foo(); return 0; }
核心原理:后置返回类型的语法允许在类成员未完全声明时,通过this指针访问后续定义的成员,编译器能正确推导返回类型。
方案2:分离声明与定义(适配C++11)
模仿C14的分离写法,用C11支持的语法替代decltype(auto):
写法A:直接指定返回类型
#include <vector> class Demo { public: std::vector<int> foo(); private: std::vector<int> m_data; }; std::vector<int> Demo::foo() { return m_data; } int main() { Demo demo; auto data = demo.foo(); return 0; }
写法B:用decltype推导类型(避免写死类型)
借助std::declval(C++11可用)获取类类型的引用,从而推导成员变量的类型:
#include <vector> #include <utility> // 引入std::declval class Demo { public: decltype(std::declval<Demo>().m_data) foo(); private: std::vector<int> m_data; }; decltype(std::declval<Demo>().m_data) Demo::foo() { return m_data; } int main() { Demo demo; auto data = demo.foo(); return 0; }
方案3:使用类型别名
在类内提前定义成员变量的类型别名,成员函数直接使用别名,成员变量后置:
#include <vector> class Demo { public: using DataT = std::vector<int>; DataT foo(){ return m_data; }; private: DataT m_data; }; int main() { Demo demo; auto data = demo.foo(); return 0; }
优势:代码可读性高,同时保证类型一致性,后续修改类型只需改动别名定义。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

