How string accepting interface should look like?
<p>This is a follow up of <a href="http://stackoverflow.com/questions/4640281/design-of-stdifstream-class">this question</a>. Suppose I write a C++ interface that accepts or returns a const string. I can use a const char* zero-terminated string:</p>

<pre><code>void f(const char* str); // (1)
</code></pre>

<p>The other way would be to use an std::string:</p>

<pre><code>void f(const string&amp; str); // (2)
</code></pre>

<p>It's also possible to write an overload and accept both:</p>

<pre><code>void f(const char* str); // (3)
void f(const string&amp; str);
</code></pre>

<p>Or even a template in conjunction with boost string algorithms:</p>

<pre><code>template&lt;class Range&gt; void f(const Range&amp; str); // (4)
</code></pre>

<p>My thoughts are:</p>

<ul>
<li>(1) is not C++ish and may be less efficient when subsequent operations may need to know the string length.</li>
<li>(2) is bad because now <code>f("long very long C string");</code> invokes a construction of std::string which involves a heap allocation. If <code>f</code> uses that string just to pass it to some low-level interface that expects a C-string (like fopen) then it is just a waste of resources.</li>
<li>(3) causes code duplication. Although one <code>f</code> can call the other depending on what is the most efficient implementation. However we can't overload based on return type, like in case of std::exception::what() that returns a const char*.</li>
<li>(4) doesn't work with separate compilation and may cause even larger code bloat. </li>
<li>Choosing between (1) and (2) based on what's needed by the implementation is, well, leaking an implementation detail to the interface.</li>
</ul>

<p>The question is: what is the preffered way? Is there any single guideline I can follow? What's your experience?</p>

<p><strong>Edit:</strong> There is also a fifth option:</p>

<pre><code>void f(boost::iterator_range&lt;const char*&gt; str); // (5)
</code></pre>

<p>which has the pros of (1) (doesn't need to construct a string object) and (2) (the size of the string is explicitly passed to the function).</p>
