Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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..

like image 501
aydow Avatar asked Nov 17 '16 06:11

aydow


People also ask

What are the parameter passing techniques in C++?

Parameter Passing Techniques in C/C++. There are different ways in which parameter data can be passed into and out of methods and functions. Let us assume that a function B() is called from another function A(). In this case A is called the “caller function” and B is called the “called function or callee function”.

How do you pass parameter data from one method to another?

There are different ways in which parameter data can be passed into and out of methods and functions. Let us assume that a function B () is called from another function A (). In this case A is called the “caller function” and B is called the “called function or callee function”.

What is difference between actual parameter and formal parameter in C++?

Formal Parameter : A variable and its type as they appear in the prototype of the function or method. Actual Parameter : The variable or expression corresponding to a formal parameter that appears in the function or method call in the calling environment. IN: Passes info from caller to calle. OUT: Callee writes values in caller.

How do you pass an iterable to the front in C++?

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);


1 Answers

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.

like image 50
Justin Avatar answered Sep 30 '22 16:09

Justin