How string accepting interface should look like?

Posted by ybungalobill on Stack Overflow See other posts from Stack Overflow or by ybungalobill
Published on 2011-01-09T17:43:22Z Indexed on 2011/01/09 17:53 UTC
Read the original article Hit count: 185

Filed under:

Hello,

This is a follow up of this question. Suppose I write a C++ interface that accepts or returns a const string. I can use a const char* zero-terminated string:

void f(const char* str); // (1)

The other way would be to use an std::string:

void f(const string& str); // (2)

It's also possible to write an overload and accept both:

void f(const char* str); // (3)
void f(const string& str);

Or even a template in conjunction with boost string algorithms:

template<class Range> void f(const Range& str); // (4)

My thoughts are:

  • (1) is not C++ish and may be less efficient when subsequent operations may need to know the string length.
  • (2) is bad because now f("long very long C string"); invokes a construction of std::string which involves a heap allocation. If f 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.
  • (3) causes code duplication. Although one f 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*.
  • (4) doesn't work with separate compilation and may cause even larger code bloat.
  • Choosing between (1) and (2) based on what's needed by the implementation is, well, leaking an implementation detail to the interface.

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

© Stack Overflow or respective owner

Related posts about c++