Making C++11 range-based for loops a bit more useful C++11 is great. Probably one of the most beautiful features (in my opinion) is the so-called range-based-for-loop.
Instead of

for ( std::size_t i(0); i &lt; range.size(); ++i )
{
   // do something to range[i];
}


or

for ( Range::iterator it(range.begin()); it != range.end(); ++it )
{
   // do something to *it;
}


or simplified with C++11 auto:

for ( auto it(range.begin()); it != range.end(); ++it )
{
   // do something to *it;
}


we can say this:

for ( auto&amp; entry : range )
{
   // do something with entry.
}


This is very expressive: We talk about the entry, rather than the i^th position in the range or the iterator pointing to an entry. However, this syntax lacks the ability of having subranges (e.g. ignoring the last entry). In a series of small helper structs / methods, I want to add this functionality in a clean way.

So much for my motivation ;-) Now, for the real deal.

In this post, I address conditions on the entries of range. Basically, the helper code should perform the equivalent of

for ( auto&amp; entry : range )
{
   if ( condition(entry) )
   {
       // do something to entry.
   }
}


but without that level of indentation.

Here is the code for ConditionalRange:

template &lt;typename Range, typename Runnable&gt;
ConditionalRange&lt;Range, Runnable&gt; makeConditionalRange(Range&amp; range, Runnable&amp;&amp; condition)
{
   static_assert(std::is_same&lt;decltype(condition(*std::declval&lt;Range&gt;().begin())), bool&gt;::value, "Condition must return a boolean value.");
   return ConditionalRange&lt;Range, Runnable&gt;(range, std::forward&lt;Runnable&gt;(condition));
}

template &lt;typename Range, typename Runnable&gt;
struct ConditionalRange
{
   public:
      friend ConditionalRange makeConditionalRange&lt;&gt;(Range&amp;, Runnable&amp;&amp;);
   public:
      using iterator_type = ConditionalIterator&lt;decltype(std::declval&lt;Range&gt;().begin()), Runnable&gt;;
      iterator_type begin() const
      {
         auto b = range.begin();
         while ( b != range.end() &amp;&amp; !condition(*b) )
         {
            ++b;
         }
         return ConditionalIterator&lt;decltype(std::declval&lt;Range&gt;().begin()), Runnable&gt;(b, range.end(), condition);
      }
      iterator_type end() const
      {
         return ConditionalIterator&lt;decltype(std::declval&lt;Range&gt;().begin()), Runnable&gt;(range.end(), range.end(), condition);
      }
   private:
      ConditionalRange(Range&amp; range_, Runnable&amp;&amp; condition_)
      :
         range(range_),
         condition(std::forward&lt;Runnable&gt;(condition_))
      {
      }
   private:
      Range&amp; range;
      Runnable condition;
};


This is the helper struct for the iterator:

template &lt;typename Iterator, typename Runnable&gt;
struct ConditionalIterator
{
   private:
      Iterator iterator;
      Iterator end;
      const Runnable&amp; condition;
   public:
      ConditionalIterator(Iterator b, Iterator e, const Runnable&amp; r)
      :
         iterator(b),
         end(e),
         condition(r)
      {
      }
      auto operator*() -&gt; decltype(*iterator)
      {
         return *iterator;
      }
      ConditionalIterator&amp; operator++()
      {
         do
         {
            ++iterator;
         }
         while ( iterator != end &amp;&amp; !condition(*iterator) );
         return *this;
      }
      bool operator==(const ConditionalIterator&amp; second)
      {
         return iterator == second.iterator;
      }
      bool operator!=(const ConditionalIterator&amp; second)
      {
         return !(*this == second);
      }
};


The intended usage is:

std::vector&lt;int&gt; ns{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for ( const auto&amp; n : makeConditionalRange(ns, [](int a) { return a % 2 == 0; }) )
{
   std::cout &lt;&lt; n &lt;&lt; " ";
}
std::cout &lt;&lt; "\n";


Demo: click here!

What are weaknesses of my approach? With what kind of arguments does it fail, although it shouldn't in the perfect world?
You can use braces to return from your functions. That way, you won't have to repeat long and cumbersome types (DRY, as much as possible). For example, ConditionalRange::end:

iterator_type end() const
{
    return { range.end(), range.end(), condition };
}


Also, you probably want your function to accept C-style arrays too. Therefore, you should use std::begin and std::end instead of calling the member functions:

iterator_type end() const
{
    return { std::end(range), std::end(range), condition };
}


With that (everywhere in your code) and some trivial changes, your code will also work for C-style arrays (tested here and it works fine).

Naming your function

The name makeConditionalRange is quite long. The function you created already exists in other libraries and programming languages (Python comes to my mind) under the name filter. You should consider changing its name in order for many users to recognize the name at first glance (moreover, it will be shorter).