bkxp
bkxp

Reputation: 1145

Template code blocks in C++?

Recently I was working on a project, which required a lot of constructs like "repeat" and "foreach". I know that there are no such constructs in C++, but I tried to imagine what they might look like.

repeat(count)
{
   ...
}

foreach(someList, it)
{
   ...
}

Since template inline functions are already supported in C++, very little change is required to support template code blocks also. One of possible syntax could be like this:

template<unsigned count> repeat(unsigned count)
while(count--) __code;

template <class ContainerT, typename ContainerT::iterator it>
foreach(ContainerT& cn, typename ContainerT::iterator it)
    for(typename ContainerT::iterator it=cn.begin(); it!=cn.end(); ++it) __code;

What do you think about this syntax? Is there any chance for such feature to be added in future C++ versions? Do you know any workarounds to implement something like this in the current C++ version?

Upvotes: 1

Views: 3737

Answers (2)

Some programmer dude
Some programmer dude

Reputation: 409196

Instead of having a proper body for the loops, look at how the C++ standard library does it: It uses "predicates" as arguments to similar functions, and these can be any callable object (function pointers, static member function pointers, functor objects, and (since C++11) std::function objects, std::bind expressions or lambda expressions).

So your repeat function could be something like this:

template<typename Tpred>
void repeat(unsigned count, Tpred predicate)
{
    while (count--)
        predicate();
}

The above function could be used as

repeat(10, [](){ std::cout << "hello\n"; });

The call above would cause the lambda to be called ten times, so it would print "hello" ten times.

Upvotes: 1

Andy Prowl
Andy Prowl

Reputation: 126452

Is there any chance for such feature to be added in future C++ versions?

C++11 has range-based for loops:

for (auto elem : cont) // (perhaps use auto&, auto const&, or auto&&,
                       //  depending on your use case)
{
    // Do what you want with elem...
}

Alternatively, you can use std::for_each() with a lambda:

std::for_each(cont.begin(), cont.end(), 
    [&] (decltype(cont)::value_type const& elem)
//                                  ^^^^^^
//                                  Or whatever fits your needs
{
    // Do what you want with elem...
}

Also, Boost.Range has versions of the C++ Standard algorithms that allow working on ranges rather than on pairs of iterators:

#include <boost/range/algorithm.hpp>

// ...

std::vector<int> v = { 1, 2, 3 };
boost::for_each(v, [] (int i) { std::cout << i * 2 << std::endl; });

Upvotes: 3

Related Questions