2

Why const std::string str="__$HOOK_FUNC_FOR_LUA_KEY@__"; is ok whereas the compiler complains when compiling

const std::string str("__$HOOK_FUNC_FOR_LUA_KEY@__");?

NOTE: str is a member variable of a C++ class.

Demo code:

class Demo
{
private:
const std::string str("__$HOOK_FUNC_FOR_LUA_KEY@__");
}

Here are the the error messages:

test.hpp:253:51: error: expected identifier before string constant
     const std::string str("__$HOOK_FUNC_FOR_LUA_KEY@__");
                                                   ^
test.hpp:253:51: error: expected ‘,’ or ‘...’ before string constant

It's obvious that there is ctor for std::string(char*). So I am really confused.

John
  • 2,963
  • 11
  • 33
  • It does work with curly brace initialization `str { "xxx" }`. I think that the issue is that the compiler has problem distinguishing whether `str` is a member or function when using round brackets `()`. – freakish Dec 18 '20 at 08:36
  • 1
    got a similar post here -> https://stackoverflow.com/questions/10052135/expected-identifier-before-string-constant – Arsenic Dec 18 '20 at 08:38
  • The [most vexing parse](https://en.wikipedia.org/wiki/Most_vexing_parse) has striked again! The compiler sees that as a function declaration and emits a confusing message. Don't worry about it, most of us were caught... – Serge Ballesta Dec 18 '20 at 08:39
  • @SergeBallesta: In fact, to avoid possible (most) vexing parse, that construct is simply forbidden. (inconsistency with initialization of regular variable). – Jarod42 Dec 18 '20 at 10:53

2 Answers2

5

You can't have function-like inittialization inline in classes. You must use curly-braces {} or "assignment" like syntax with =.

It's a way to go around the problem of detecting if you're declaring a function or a variable.

And as you're dealing with std::string which has an std::initializer_list constructor (which will be used for curly-brace initialization) you can only use assignment-like syntax:

const std::string str = "__$HOOK_FUNC_FOR_LUA_KEY@__";

Of course, you can use a constructor initializer list as well:

Demo()
    : str("__$HOOK_FUNC_FOR_LUA_KEY@__")
{}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • "It's a way to go around the problem of detecting if you're declaring a function or a variable?" You mean there is no other method to achieve this goal? – John Dec 18 '20 at 11:44
  • @John Unfortunately there's something in C++ called [*the most vexing parse*](https://en.wikipedia.org/wiki/Most_vexing_parse), where there's an ambiguity between variable definitions and function declarations. This was a way to not worry about it. – Some programmer dude Dec 18 '20 at 12:36
2

For initializing of member variable you can use:

  1. Member initialize list:
A () : m_var ("something") {}
  1. Copy initialization:
struct A
{
  std::string m_var = "something";
};
  1. Value or list initialization:
struct A
{
  std::string m_var {"something"};
};

From CppReference:

https://en.cppreference.com/w/cpp/language/data_members#Member_initialization

Ghasem Ramezani
  • 2,683
  • 1
  • 13
  • 32