带decltype的auto返回值成员函数能否分离头文件与实现?
带decltype的auto后置返回值函数能否分离头文件与实现?
首先可以明确:这类函数完全可以分离头文件和实现,你遇到的问题主要是代码写法错误+MSVS2012对C++11特性的支持局限性导致的。
先看你代码里的直接错误:在cpp文件的函数实现中,你写了return mymap->equal_range(key_val);——但mymap是mymapclass的成员对象(不是指针),应该用.而不是->访问成员函数,这正是MSVS报错C2228的直接原因(你试图在非类/结构体/联合的对象上用->)。
除了这个语法错误,还有一个关于decltype上下文的问题需要注意:在类外部定义带后置返回值的函数时,编译器无法直接识别mymap是mymapclass的成员,所以需要明确提供上下文。
修正后的正确代码示例
头文件(比如mymapclass.h)
#include <map> #include <utility> // 用于std::declval class mymapclass { std::multimap<int, int> mymap; public: // 声明时,因为在类内部,编译器能识别mymap是成员,所以写法没问题 auto get_mymap_value_range(int key_val) -> decltype(mymap.equal_range(key_val)); };
cpp文件(mymapclass.cpp)
#include "mymapclass.h" // 定义时,用std::declval生成一个mymapclass的临时对象,明确mymap的所属 auto mymapclass::get_mymap_value_range(int key_val) -> decltype(std::declval<mymapclass>().mymap.equal_range(key_val)) { // 修正指针访问错误,用.访问成员函数 return mymap.equal_range(key_val); }
或者你也可以用this->来提供上下文(不过MSVS2012对this在后置返回值中的支持可能不稳定):
auto mymapclass::get_mymap_value_range(int key_val) -> decltype(this->mymap.equal_range(key_val)) { return mymap.equal_range(key_val); }
额外说明
- 关于MSVS2012的局限性:作为比较早的支持C11的编译器,它对很多C11特性的支持并不完善,比如后置返回值中的成员访问、
decltype的某些用法。如果上述修正后还是有问题,建议考虑升级到更高版本的Visual Studio(比如2017及以后),对C++标准的支持会更完整。 - 临时妥协方案:如果暂时无法升级编译器,把函数实现留在头文件中(作为inline函数)是可行的,这也是你最初能正常运行的原因——类内部的函数默认是inline,编译器能直接获取到
mymap的上下文和完整类型信息。
内容的提问来源于stack exchange,提问作者code_fodder
相关产品推荐
相关产品推荐

