3

I don't understand the significance of using two double quotes with strings in C++. I saw the following code somewhere:

class str_literal;
static str_literal operator"" _s(const char *s, size_t len);

class str_literal {
private:
  explicit str_literal(const char *s)
      : m_str(s) //&(STRING_LITERAL(s)))
  {}
  const char *m_str;

public:
  friend str_literal operator"" _s(const char *s, size_t len);
};
static str_literal operator"" _s(const char *s, size_t len) {
  return str_literal(s);
}
#define S(str) "" str "" _s

Why not make the constructor public and just do this?

#define S(str) str_literal(str)
Manthan Tilva
  • 3,135
  • 2
  • 17
  • 41
nishantsingh
  • 4,537
  • 5
  • 25
  • 51
  • 1
    The preprocessor would no be able to distinguish `str` inside `str_s`, in order to replace it with the input argument. There is a specific set of proper delimiters which allow the preprocessor to determine the tokens in every given expression (white spaces, round brackets, and that's pretty much it I believe). – goodvibration Dec 02 '19 at 11:49
  • Got it. Removed the last part of question. Still is that the only purpose of using two double quotes ? I am seeing this syntax for the first time. – nishantsingh Dec 02 '19 at 11:55
  • 1
    I think this should help answer your question https://en.cppreference.com/w/cpp/language/user_literal if you're not just referring to the preprocessor stringify – UKMonkey Dec 02 '19 at 11:58
  • 1
    The constructor isn't public in order to disable the creation of "non-literal literals" ; you're not supposed to be able to write `str_literal(some_function())`. – molbdnilo Dec 02 '19 at 12:04
  • 1
    [how-to-compose-stringification-with-user-defined-literal-udl-in-macro](https://stackoverflow.com/a/58868807/2684539) shows alternative to string concatenation – Jarod42 Dec 02 '19 at 13:51

1 Answers1

1

They’re unnecessary. Whoever wrote the code probably intended to use the fact that you the preprocessor concatenates successive C string literals into one literal so that e.g. S("hi") results in "" "hi" ""_s, which, in turn, results in "hi"_s.

However, there is no need to have the first "" in the macro definition. And there’s no need for the second "" either, since we can use the token pasting operator ## instead:

#define S(str) str ## _s

This has the exact same effect, and is idiomatic.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • Why not do `#define S(str) ""str""_s` ? What's the importance of spaces? – nishantsingh Dec 02 '19 at 12:04
  • 1
    (Most of) the spaces are also unnecessary but many people would find this confusing, because `""`, `str` and `""` are actually distinct tokens, yet putting them directly adjacent without spaces suggests that they form a single preprocessor token. Similarly in my code, `##` is an operator, so I always surround it with spaces. What’s more, there *needs* to be a space between the initial `""` and `str`, because `""str` *does* form a token for the preprocessor, so it won’t try replacing `str`. – Konrad Rudolph Dec 02 '19 at 12:12