On 07.12.16 00.40, Stefan Ram wrote:
> Today, I read a bit in an Ocaml manual which said
>
> insert elt lst =
> match lst with
> [] -> [elt]
> | head :: tail -> if elt <= head then elt :: lst else head :: insert elt tail
>
> as a part of an insertation-sort program.
>
> I was trying to translate that into C++, and got this:
>
> template< class L, class I, class T >
> void insert( L & lst, I bbegin, I begin, I end, T elt )
> { if( begin == end )lst.insert_after( bbegin, elt ); else
> { if( elt <= lst.front() )lst.insert_after( bbegin, elt ); else
> insert( lst, ++bbegin, ++begin, end, elt ); }}
This is buggy as lst.front() will not take care of the incremented begin
iterator on recursive calls. It just happens to work for your test case.
> Can my C++ ::insert function be simplified?
Well, in C++ probably nobody would write this as a recursion.
But, of course, this could be done.
At least you could eliminate the parameters begin and end and the
duplicate insert_after.
void insert(L& lst, I bbegin, T elt)
{ I old_begin = bbegin++;
if (bbegin == lst.end() || elt <= *bbegin)
lst.insert_after(old_bbegin, elt);
else
insert(lst, bbegin, elt);
}
But as already mentioned, a simple while loop would do the job even
better and eliminates the bbegin parameter too.
OK, if the compiler can handle TCO the generated code might be almost
the same and not recursive in both cases. But it cannot eliminate the
additional bbegin parameter at the initial call from main unless
everything is inlined.
Marcel