I have run into an interesting challenge that I have been trying to solve for hours, but after much research and many failed attempts, I find myself asking this question.
I would like to write 3 overloaded functions that each take one of the following types: const char*
, const char(&)[N]
and string literal (e.g. "BOO")
. I understand that a string literal is simply a char array, but please bear with me while I explain my approach.
The two functions below are able to differentiate between the first two types (const char*
and const char(&)[N]
) thanks to the wrapper class CharPtrWrapper
:
#include <iostream>
class CharPtrWrapper
{
public:
CharPtrWrapper(const char* charPtr)
: m_charPtr(charPtr)
{
}
const char * m_charPtr;
};
void processStr(CharPtrWrapper charPtrWrapper)
{
std::cout << "From function that takes a CharPtrWrapper = " << charPtrWrapper.m_charPtr << '\n';
}
template<std::size_t N>
void processStr(const char (&charArr)[N])
{
std::cout << "From function that takes a \"const char(&)[N]\" = " << charArr << '\n';
}
int main()
{
const char* charPtr = "ABC";
processStr(charPtr);
const char charArr[] = {'X', 'Y', 'Z', '\0'};
processStr(charArr);
}
Output:
From function that takes a CharPtrWrapper = ABC
From function that takes a "const char(&)[N]" = XYZ
Now, if I call processStr
with a string literal (e.g. processStr("BOO")
), the version that takes a const char(&)[N]
gets called, which makes sense, since a string literal is simply a char array.
Here is where I reach the crux of the problem. I have not been able to write a function that is able to differentiate between a char array and a string literal. One thing I thought might work was to write a version that takes an rvalue reference:
template<std::size_t N>
void processStr(const char (&&charArr)[N])
{
std::cout << "From function that takes a \"const char(&&)[N]\" = " << charArr << '\n';
}
But it turns out that string literals are lvalues. I have also played with different versions that use std::enable_if
and std::is_array
, but I still don't get the result I'm looking for.
So I guess my question is the following: is it possible to differentiate between char arrays and string literals in modern C++?