Java Iterator in C++

Tags: , ,



I am a Java user and I am getting into C++ and in Java it allows classes to reveal Iterable types so clients can traverse some instance’s collection of data. Is there any way to obtain this functionality in C++? This is an example of what I am trying to implement in c++.

 public Iterable<String> keys() {
    Queue<String> queue = new Queue<String>();
    collect(root, new StringBuilder(), queue);
    return queue;

Answer

C++ is not object oriented in the same way as Java. While containers do have some uniformity in their interface, they do not implement a common interface type or derive from a common base. These types of implicit interfaces allow compile-time polymorphism only, so you there isn’t any Iterable abstraction equivalent which can allow standard containers to be used polymorphically at runtime. You would just return the actual type being created.

Type deduction (see auto) will solve most problems you may be expecting from such a solution. It allows the compiler to decide the appropriate type to use to store a value, allowing for the kind of generalization you may be looking for with this question.

Here is a possible implementation (try it here) :

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <vector>

template<class T>
auto map_keys(const T & container)
{
    auto result = std::vector<typename T::key_type>{};
    std::transform(
        std::begin(container), std::end(container),
        std::back_inserter(result),
        [](const auto & pair) { return pair.first;});
    return result;
}

int main()
{
    auto my_map = std::map<std::string, int>{
        {"foo", 10},
        {"bar", 20},
        {"baz", 30} };
    
    auto keys = map_keys(my_map);

    for(const auto & key : keys)
    {
        std::cout << key << 'n';
    }
}

Hopefully it helps to illustrate that in C++ generalization is often achieved using compile-time polymorphism, as opposed to Java which uses exclusively (as far as I know) runtime polymorphism.

If you actually need runtime polymorphism, for example if you are trying to build a homogeneous container of iterable ranges, there may be solutions but they are not convenient and certainly not idiomatic. C++ is a strongly typed language, and due to its use of value semantics and allowing the user strict control of resource ownership, it is very hard to abstract away type information at runtime unless the relevant types are already designed to be used that way. And standard containers are not designed to be runtime polymorphic.



Source: stackoverflow