I have to write a library which contains a function that takes two strings parameters:
void foo(const std::string& arg1, const std::string& arg2);
My library is going to be used by some people that don’t like C++ and are only used to const char*.
To satisfy their likes, I changed the prototype:
void foo(const char* arg1, const char* arg2);
And made my first version a simple inline call:
inline void foo(const std::string& arg1, const std::string& arg2)
{
foo(arg1.c_str(), arg2.c_str());
}
Of course, thanks to the std::string constructors, it would have worked almost the same way with just the first version. Writing this overload just avoids instanciating useless std::string in the case someone passes only const char*.
But now I wonder: is this overload really necessary or is it just premature optimization ?
Also, I’m feeling like this is somehow incomplete: should I write also void foo(const char* arg1, const std::string& arg2) and void foo(const std::string& arg1, const char* arg2) overloads ? What if I have 3, 4 or more (n) parameters ? Should I write 2n overloads ?
In short, have you ever faced a similar situation ? What choices did you made and why ?
Thank you.
IMO it’s reasonable to have two overloads to handle two different programming styles that co-exist within your organization.
Technically it’s not just an optimization:
const char*can beextern "C", so might be useful for bindings from other languages, or even from other C++ code across a dll boundary with incompatible standard library implementation.std::stringcan throwbad_alloc, so if it cannot otherwise fail then theconst char*version is useful if you have a C-style string and want to use it in a nothrow context.Also beware that in principle
c_str()can throwbad_alloc, but I doubt that any implementations actually do.2n overloads doesn’t seem worthwhile to me – if someone is mixing
stringandchar*then it’s not just a programming style difference, they’re actually using mixed formats for some reason. Since they’re using both already, they can convert for themselves.This all assumes that the function is simple enough that you’re happy to implement the actual work with
const char*parameters. If the implementation based onstringwould be significantly simpler (for example if it takes significant code to make it exception-safe otherwise), then that probably wins over efficiency anyway, so don’t provide any overloads, let theirconst char*convert tostring.