c++iterablegeneric-type-argument

C++: How to pass any iterable type as a function parameter


As an exercise I'm trying to implement Python's str.join method in C++. I will eventually add the function as a method of the std::string class but I figure getting it to work is more of a priority. I've defined the function as follows:

template<typename Iterable>
std::string join(const std::string sep, Iterable iter);

Is there any way that I can ensure that the Iterable type is actually iterable? E.g. I wouldn't want to receive an int or char..


Solution

  • In C++, rather than having one Iterable, we pass in an iterator (almost a pointer) to the front and the end of the range:

    template<typename Iter>
    std::string join(const std::string &sep, Iter begin, Iter end);
    

    Note that the sep should be passed as const reference, as you don't need to copy it.

    You don't need to worry about whether the Iter is actually an iterator, though. This is because the code will simply fail to compile if it doesn't work.

    For example, suppose you implemented it like so (this is a bad implementation):

    template<typename Iter>
    std::string join(const std::string &sep, Iter begin, Iter end) {
        std::string result;
    
        while (begin != end) {
            result += *begin;
            ++begin;
            if (begin != end) result += sep;
        }
    
        return result;
    }
    

    Then the type passed in as Iter must have an operator++, an operator!=, and an operator* to work, which is the well understood contract of an iterator.