
Hi, Looking at the code generated by MSVC++ 2008 from a call to boost::algorithms::replace_all with std::wstrings as arguments I came across this remarkable piece of work: === cut === ; 109 : return range_detail::make_range( r, range_detail::is_char_ptr(r) ); xor eax, eax push -1 mov WORD PTR $T115029[esp+44], ax push eax mov eax, edi lea ecx, DWORD PTR $T115029[esp+44] mov DWORD PTR $T115029[esp+68], 7 mov DWORD PTR $T115029[esp+64], 0 call ?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator... cmp DWORD PTR $T115029[esp+60], 8 jb SHORT $LN52@as_literal mov ecx, DWORD PTR $T115029[esp+40] push ecx call ??3@YAXPAX@Z ; operator delete ... === cut === Checked it with g++ -O2 and found that it produced something similar: === cut === 109:.../boost/boost/range\as_literal.hpp **** return range_detail::make_range( r, range_detail::is_char_ptr(r) ); leal 168(%esp), %ebx movl %ebx, 4(%esp) leal 164(%esp), %eax movl %eax, (%esp) call __ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_ movl 168(%esp), %eax movl %eax, 44(%esp) movl -12(%eax), %edx movl %edx, 52(%esp) movl 164(%esp), %eax leal -12(%eax), %ebx cmpl $__ZNSbIwSt11char_traits..._Rep20_S_empty_rep_storageE, %ebx jne L412 L284: ... L412: movl 8(%ebx), %eax leal -1(%eax), %edx movl %edx, 8(%ebx) testl %eax, %eax jg L284 leal 188(%esp), %eax movl %eax, 4(%esp) movl %ebx, (%esp) call __ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1_ jmp L284 === cut === I.e., even with the optimization turned on, a call to "inline" function template< class T > inline long is_char_ptr( T /* r */ ) { return 0L; } in boost/range/as_literal.hpp causes the creation of a temporary copy of every string passed to boost::as_literal. :( I believe it would have been better to define that function as template< class T > inline long is_char_ptr(const T& /* r */ ) { return 0L; } Serge