Are these overloads necessary?

I need to write a library that contains a function that takes two string parameters:

void foo(const std::string& arg1, const std::string& arg2); 

My library will be used by some people who do not like C ++ and are used only for const char* .

To satisfy my 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 work almost the same way as with the first version. Writing this overload simply avoids creating a useless std::string if someone passes only const char* .

But now I wonder: is this overload really necessary or is it just a premature optimization?

In addition, I feel that this is somehow incomplete: should I also write void foo(const char* arg1, const std::string& arg2) and void foo(const std::string& arg1, const char* arg2) overloads? What if I have options 3, 4 or more ( n )? Should I write 2 n overloads?

In short, have you ever encountered a similar situation? What choice did you make and why?

Thanks.

+6
source share
6 answers

IMO, it makes sense to have two overloads to handle two different programming styles that coexist in your organization.

Technically, this is not just optimization:

  • const char* can be extern "C" , therefore it can be useful for bindings from other languages ​​or even from other C ++ code across the dll border with an incompatible implementation of the standard library.
  • converting to std::string can throw bad_alloc , so if it cannot fail otherwise, then the const char* version is useful if you have a C style string and want to use it in a fuzzy context.

Also beware that, in principle, c_str() can throw bad_alloc , but I doubt that any implementations are actually running.

2 n overloads do not seem to me useful - if someone mixes string and char* , then this is not just a difference in programming style, they actually use mixed formats for some reason. Since they already use both, they can convert for themselves.

All this assumes that this function is simple enough that you are happy to implement the actual work with const char* parameters. If a string based implementation is much simpler (for example, if it requires significant code to make it exclusive security otherwise), then it is likely to win over efficiency anyway, so don't create overloads, let them convert const char* in string .

+4
source

As long as you want to work with C ++ (and not C), the second seems unnecessary if you have this:

 void foo(const std::string& arg1, const std::string& arg2); 

You can call this with all combinations of std::string and char* like:

 char *ca, *cb; std::string sa, sb; //... foo(ca,cb); //char*, char* foo(sa,cb); //std:string, char* foo(sa,sb); //std::string, std::string foo(ca,sb); //char*, std::string 
+2
source

If const char * text never null, you can use string because it has an implictit constructor, so the version of the string class may be sufficient. In the other hand: if const char * text can be empty, it generates a runtime error.

One more thing: STL is not a good option on the DLL interface. Therefore, if this function is part of the DLL interface, you can use C style strings.

I can do it like this:

 #include <string> using namespace std; void foo( const string arg0, const string arg1 ) extern "C" _declspec( dllexport ) void foo( const char * arg0, const char * arg1 ) { string string_arg0, string_arg1; if ( arg0 != 0 ) string_arg0 = arg0; if ( arg1 != 0 ) string_arg1 = arg1; foo(string_arg0, string_arg1); } 
+1
source

I think your current approach is correct. Where you overload for const char* and provide a wrapper that also serves as std::string .

If your colleagues will use a C-style character pointer, what better way to do it (current path). See the following example:

 char *p = 0; foo(p); void foo (const string &s) { // runtime error } 

Demo Since you can see that pointers to characters may not always go well with std::string ; so why take the risk. Even if people cannot do such coding; nevertheless, you must avoid such potential dangers for long-term maintainability.

Inside a function, you can always select std::string from const char* and write your own algorithm.

0
source

In this case, you could just have (const char *, const char *) and ask everyone using std :: string to use c_str (). Thus, there will be no overhead for memory allocation, but only additional c_str () that people will need to put together.

0
source

My library will be used by some people who do not like C ++ and are used only for const char *.

Tell them to raise the language and learn the language that the compiler compiles. You take std::string , because how to do it in C ++, and if they don't like it, then they can get the C compiler.

0
source

Source: https://habr.com/ru/post/893848/


All Articles