The following code compiles fine in C++ 20 (e.g., using https://www.onlinegdb.com/online_c++_compiler) when using auto
as a return type of get_map_values_iterator()
. However, I want to split this class into implementation and header files, and it seems I cannot use auto
as a return type in a class header (which I think I understand why).
So I have tried spelling out the type name of the return value with the help of my IDE, and I came up with
std::ranges::elements_view<std::ranges::ref_view<std::map<int, std::string>>, 1>::_Iterator<true>
However, _Iterator
seems to be private, and I am getting errors such as
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 // this works
std::ranges::elements_view<std::ranges::ref_view<std::map<int, std::string>>, 1>::_Iterator<true> // this fails
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;
}
I have also figured out that I can implement this function (with auto
) in the header file, which is an OKish workaround. But to do it properly, how can I define a class function in an implementation file that returns iterator
?
I suppose begin()
is not the only iterator that needs to be returned, thus trailing return type -> decltype()
is overwording. You can use a deduced iterator type as a user type:
#include <map>
#include <ranges>
#include <string>
class A {
private:
std::map<int, std::string> my_map;
public:
using my_iterator = decltype(std::ranges::views::values(my_map).begin());
my_iterator get_map_begin();
my_iterator get_map_end();
};
int main() {
A a;
a.get_map_begin();
a.get_map_end();
return 0;
}
A::my_iterator A::get_map_begin() {
const auto& values = std::ranges::views::values(my_map);
auto iterator = values.begin();
return iterator;
}
A::my_iterator A::get_map_end() {
const auto& values = std::ranges::views::values(my_map);
auto iterator = values.end();
return iterator;
}