0

My question is:

Is there a way to determine whether a parameter is a literal string or not?

template<class T>
bool IsLiteral(T arg)
{
    // How to implement?
}

or

template<class T>
struct IsLiteral { enum { value = ??? }; };

So that we can write the following code:

char* p = "Hello";

assert(IsLiteral(p)); // fail.
assert(IsLiteral("Hello")); // never fail.
assert(IsLiteral<decltype("Hello")>::value); // never fail.
cHao
  • 84,970
  • 20
  • 145
  • 172
xmllmx
  • 39,765
  • 26
  • 162
  • 323
  • I suppose you could make it fail when it doesn't satisfy `const char *&&`, but that wouldn't only succeed for literals. I have no idea why you want this functionality. – chris Sep 16 '13 at 03:02
  • @Shafik, literal strings are related to C. – xmllmx Sep 16 '13 at 03:03
  • 2
    @xmllmx literal strings are related to C, but templates aren't. – Sergey Kalinichenko Sep 16 '13 at 03:05
  • Another possible duplicate: [Can a compilation error be forced if a string argument is not a string literal?](http://stackoverflow.com/q/18563585/420683) – dyp Sep 16 '13 at 03:27
  • @DyP I did not even think to look ... my those macros are ugly ... if I think about it [user define literals](http://en.cppreference.com/w/cpp/language/user_literal) could be a nice alternative depending on the use case. – Shafik Yaghmour Sep 16 '13 at 03:31
  • @chris: Knowing if something was a string literal would be very useful. You would then be able to make an encapsulating `string_ref` like class for which you could guarantee that the source string would never change and would always be valid. – Benjamin Lindley Sep 16 '13 at 03:50
  • @BenjaminLindley, Fair enough :) – chris Sep 16 '13 at 03:52
  • Note that `char* p = "Hello";` should not compile on newer compilers since `"Hello"` is a `char const *` and thus it can't be assigned to a `char *` without a `const_cast()`. – Alexis Wilke Sep 15 '21 at 16:22

3 Answers3

0

"String Literal" is a source code term. Once the code is compiled it assigns/loads it into a memory location. The code using its value doesn't care or know if it was created at runtime or compiled time.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Black Frog
  • 11,595
  • 1
  • 35
  • 66
0

There is no way to detect string literals. What can be detected is that argument is a fixed size array of char const:

template <std::size_t N>
bool IsLiteral(char const (&)[N]) {
    return true;
}
template <std::size_t N>
bool IsLiteral(char (&)[N]) {
    return false;
}
template <typename T>
bool IsLiteral(T) {
    return false;
}

I don't think you can distinguish between these two uses, however:

char const array[] = { 'a' };
IsLiteral(array);
IsLiteral("foo");
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • I knew that I've [seen this before...](http://stackoverflow.com/a/18563696/420683) ;) – dyp Sep 16 '13 at 03:26
0

Is there a way to determine whether a parameter is a literal string or not?

I don't think so, a string literal is prepocessing token and will be turned into an array of const char, so you won't be able to distinguish if such as array came from a string literal or not. If we look at the C++ draft standard section 2.14.5 String literals paragraph 8 says:

Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740