Function overload for const char *, const char (&) [N] and std :: string

I want to overload a function that works for string literals and std::string , but will generate a compile-time error for const char* parameters. The following code does almost what I want:

 #include <iostream> #include <string> void foo(const char *& str) = delete; void foo(const std::string& str) { std::cout << "In overload for const std::string& : " << str << std::endl; } template<size_t N> void foo(const char (& str)[N]) { std::cout << "In overload for array with " << N << " elements : " << str << std::endl; } int main() { const char* ptr = "ptr to const"; const char* const c_ptr = "const ptr to const"; const char arr[] = "const array"; std::string cppStr = "cpp string"; foo("String literal"); //foo(ptr); //<- compile time error foo(c_ptr); //<- this should produce an error foo(arr); //<- this ideally should also produce an error foo(cppStr); } 

I am not happy that it compiles for a char array variable, but I think there is no way around this if I want to accept string literals (if there is, tell me please)

However, I would like to avoid std::string overload accepting const char * const variables. Unfortunately, I cannot just declare a remote overload that accepts the const char * const& parameter, because this will also correspond to a string literal.

Any idea how I can make foo(c_ptr) create a compile-time error without affecting other overloads?

+3
c ++ string overloading
source share
3 answers

This code does what it needs (except for an array - literals are arrays, so you cannot separate them)

 #include <cstddef> #include <string> template <class T> void foo(const T* const & str) = delete; void foo(const std::string& str); template<std::size_t N> void foo(const char (& str)[N]); int main() { const char* ptr = "ptr to const"; const char* const c_ptr = "const ptr to const"; const char arr[] = "const array"; std::string cppStr = "cpp string"; foo("String literal"); //foo(ptr); //<- compile time error // foo(c_ptr); //<- this should produce an error foo(arr); //<- this ideally should also produce an error foo(cppStr); } 
+3
source share

In order for your remote function to not be better than the template function, so that string literals still work, the remote function must also be a template. This seems to suit your requirements (although the array is still allowed):

 template <typename T> typename std::enable_if<std::is_same<std::decay_t<T>, const char*>::value>::type foo(T&& str) = delete; 

Demo version

+3
source share

In modern versions of the language, you can create some kind of user-defined type and a user-defined literal that will create it so that you can pass "this"_SOMEWORDS , but not just c string literal, chat pointer or char array.

It definitely does not satisfy your requirements to pass a string literal, but I think it is good enough, especially since it also forbids arrays

+1
source share

All Articles