如何从C++类函数返回map-values迭代器?
问题:拆分类到头文件与实现文件时,如何声明返回范围迭代器的函数?
在C++20中,使用auto作为类成员函数get_map_values_iterator()的返回类型时可以正常编译,但拆分类到头文件和实现文件时,头文件里无法直接用auto返回类型(除非做特殊处理)。尝试手动写出迭代器的具体类型std::ranges::elements_view<std::ranges::ref_view<std::map<int, std::string>>, 1>::_Iterator<true>时,因为_Iterator是标准库的私有嵌套类型,编译报错:
main.cpp:6:83: error: ‘template struct std::ranges::elements_view > >, 1>::_Iterator’ is private within this context
原代码示例:
#include <map> #include <ranges> #include <string> class A { public: // auto // 此写法可行 std::ranges::elements_view<std::ranges::ref_view<std::map<int, std::string>>, 1>::_Iterator<true> // 此写法失败 get_map_values_iterator() { auto values = std::ranges::views::values(my_map); auto iterator = values.begin(); return iterator; } private: std::map<int, std::string> my_map; }; int main() { A a; a.get_map_values_iterator(); return 0; }
以下是几种规范的解决方案:
方法1:使用C++20的auto返回类型前置声明(推荐)
C++20支持在头文件中仅声明auto返回类型的函数,只要在实现文件中提供完整定义即可(编译器在调用点前能看到定义就可以正常推导)。这是最简洁的标准写法:
头文件 A.h:
#include <map> #include <string> class A { public: auto get_map_values_iterator(); // 仅声明,返回类型用auto private: std::map<int, std::string> my_map; };
实现文件 A.cpp:
#include "A.h" #include <ranges> auto A::get_map_values_iterator() { auto values = std::ranges::views::values(my_map); return values.begin(); }
方法2:用decltype结合declval推导返回类型
如果需要显式声明返回类型,可以通过std::declval模拟成员变量的引用,推导出迭代器的类型,避免直接引用标准库的私有嵌套类型:
头文件 A.h:
#include <map> #include <ranges> #include <string> #include <utility> // 用于std::declval class A { public: decltype(std::ranges::views::values(std::declval<std::map<int, std::string>&>()).begin()) get_map_values_iterator(); private: std::map<int, std::string> my_map; };
实现文件 A.cpp:
#include "A.h" #include <ranges> decltype(auto) A::get_map_values_iterator() { auto values = std::ranges::views::values(my_map); return values.begin(); }
方法3:自定义迭代器类型别名
在类内部定义一个类型别名,封装迭代器的具体类型,让接口更清晰:
头文件 A.h:
#include <map> #include <ranges> #include <string> #include <utility> class A { public: using value_iterator = decltype(std::ranges::views::values(std::declval<std::map<int, std::string>&>()).begin()); value_iterator get_map_values_iterator(); private: std::map<int, std::string> my_map; };
实现文件 A.cpp:
#include "A.h" #include <ranges> A::value_iterator A::get_map_values_iterator() { auto values = std::ranges::views::values(my_map); return values.begin(); }
内容的提问来源于stack exchange,提问作者bers
相关产品推荐
相关产品推荐

