Is it possible to create a constructor (or function signature, for that matter) that only accepts a string literal, but not an e.g. char const *
?
Is it possible to have two overloads that can distinguish between string literals and char const *
?
C++ 0x would kind-of allow this with a custom suffix - but I'm looking for an "earlier" solution.
Rationale: avoiding heap copy of strings that won't be modified when given as string literals.
These strings directly go to an API expecting a const char *
without any processing. Most calls do use literals requiring no additional processing, only in a few cases they are constructed. I am looking for a possibility to preserve the native call behavior.
Note: - since it comes up in the answers: the code in question does not use std::string
at all, but a good example would be:
class foo
{
std::string m_str;
char const * m_cstr;
public:
foo(<string literal> s) : m_cstr(p) {}
foo(char const * s) : m_str(s) { m_cstr = s.c_str(); }
foo(std::string const & s) : m_str(s) { m_cstr = s.c_str(); }
operator char const *() const { return m_cstr; }
}
Results:
(1) it can't be done.
(2) I realized I am not even looking for a literal, but for a compile-time-constant (i.e. "anything that needs not be copied").
I will probably use the following pattern instead:
const literal str_Ophelia = "Ophelia";
void Foo()
{
Hamlet(str_Ophelia, ...); // can receive literal or string or const char *
}
with a simple
struct literal
{
char const * data;
literal(char const * p) : data(p) {}
operator const char *() const { return data; }
};
That doesn't stop anyone from abusing it (I should find a better name...), but it allows the required optimization but remains safe by default.
The string literal is stored in the read-only part of memory by most of the compilers. The C and C++ standards say that string literals have static storage duration, any attempt at modifying them gives undefined behavior. s is just a pointer and like any other pointer stores address of string literal.
A "string literal" is a sequence of characters from the source character set enclosed in double quotation marks (" "). String literals are used to represent a sequence of characters which, taken together, form a null-terminated string.
C Language Undefined behavior Modify string literalAttempting to modify the string literal has undefined behavior. However, modifying a mutable array of char directly, or through a pointer is naturally not undefined behavior, even if its initializer is a literal string.
Working solution based on sbi idea:
struct char_wrapper
{
char_wrapper(const char* val) : val(val) {};
const char* val;
};
class MyClass {
public:
template< std::size_t N >
explicit MyClass(const char (&str)[N])
{
cout << "LITERAL" << endl;
}
template< std::size_t N >
explicit MyClass(char (&str)[N])
{
cout << "pointer" << endl;
}
MyClass(char_wrapper m)
{
cout << "pointer" << endl;
}
};
int main()
{
MyClass z("TEST1"); // LITERAL
const char* b = "fff";
MyClass a(b); // pointer
char tmp[256];
strcpy(tmp, "hello");
MyClass c(tmp); // pointer
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With