Using boost string algorithms we can write it as follows.
The loop doesn't involve any copying of the string.
#include <string>
#include <iostream>
#include <boost/algorithm/string.hpp>
int main()
{
    std::string s = "stack over   flow";
    auto it = boost::make_split_iterator( s, boost::token_finder( 
                          boost::is_any_of( " " ), boost::algorithm::token_compress_on ) );
    decltype( it ) end;
    for( ; it != end; ++it ) 
    {
        std::cout << "word: '" << *it << "'\n";
    }
    return 0;
}
Making it C++11-ish
Since pairs of iterators are so oldschool nowadays, we may use boost.range to define some generic helper functions. These finally allow us to loop over the words using range-for: 
#include <string>
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <boost/range/iterator_range_core.hpp>
template< typename Range >
using SplitRange = boost::iterator_range< boost::split_iterator< typename Range::const_iterator > >;
template< typename Range, typename Finder >
SplitRange< Range > make_split_range( const Range& rng, const Finder& finder )
{
    auto first = boost::make_split_iterator( rng, finder );
    decltype( first ) last;
    return {  first, last };
}
template< typename Range, typename Predicate >
SplitRange< Range > make_token_range( const Range& rng, const Predicate& pred )
{
    return make_split_range( rng, boost::token_finder( pred, boost::algorithm::token_compress_on ) );
}
int main()
{
    std::string str = "stack \tover\r\n  flow";
    for( const auto& substr : make_token_range( str, boost::is_any_of( " \t\r\n" ) ) )
    {
        std::cout << "word: '" << substr << "'\n";
    }
    return 0;
}
Demo:
http://coliru.stacked-crooked.com/a/2f4b3d34086cc6ec