0

I'm sorry, I haven't programmed C++ in a while, I'd like to refresh my knowledge about what exact rule I'm violating here:

I can do:

int main()
{
    int a(5);
}

but cannot do:

struct Foo
{
    int a(5); // Error: expected a type specifier / Error: syntax error, 'constant'
}

I am trying to regain some lost knowledge, can someone direct me to the rule that disallows this? I'm pretty sure there'd be a question about it on here, I couldn't find it. The only thing I remember is that the committee debated (for C++11 I think) in class constructor arguments and introduced new squiggly bracket constructor initialisers, like int a{5}; but I would like to know why int a(5); isn't allowed inside a class. Has this always been disallowed in C++?

Zebrafish
  • 11,682
  • 3
  • 43
  • 119
  • 1
    You can use assignment (`= 5`) or brace initializer (`{5}`) syntax, what you tried never was possible. – πάντα ῥεῖ Oct 14 '18 at 09:11
  • 3
    `int a(5)` in class context is a declaration of function `a`, returning an `int` and with invalid argument `5`, that's what the error message is trying to say. – Yksisarvinen Oct 14 '18 at 09:12
  • @Yksisarvinen I thought about that, about the most vexing parse issue, but having a 5 constant int in the brackets makes it unambiguous, which is why it allows it in the main function, right? I'm just wondering if a rationale was given at all to help me remember. If not, that's OK. – Zebrafish Oct 14 '18 at 09:15
  • Hmm? https://stackoverflow.com/questions/48048163/c-most-vexing-parse-when-a-number-literal-is-the-argument – StoryTeller - Unslander Monica Oct 14 '18 at 10:18
  • @StoryTeller Thanks for finding that. I assume that since πάντα ῥεῖ said declaring int a(5); in a class was NEVER possible in C++ that the title of that duplicate question is misleading in asking why in C++11. Also, the explanation in that question for why it would be disallowed is that: bar B(foo()); is ambiguous, in fact a function signature. But: int a(5) is not. I assume that's why you're allowed to write it in a function. I guess a reason hasn't been given other than that those are the rules. I'm not complaining, I don't expect everything to make sense. – Zebrafish Oct 14 '18 at 11:11

1 Answers1

3

A species of vexing parse. Names in default member initializers are supposed to be looked up in the completed class, because they are suppose to imitate constructor initializers. With (), the compiler won't be able to figure out what it's parsing, because it can refer to things declared later in the class:

struct X {
    int f(x); // function or data member?
    static const int x = 1;
};
T.C.
  • 133,968
  • 17
  • 288
  • 421
  • "Names in default member initializers are supposed to be looked up in the completed class..." Thank you, that answers it for me. I was just about to let the issue go and take it for granted, this puts it in perspective for me, that the same line is parsed differently whether it's a class member or a declaration in a function, it seems. Thank you. – Zebrafish Oct 14 '18 at 09:24
  • Umm, just one thing though, doesn't int f(5); not allow for any ambiguity because the constructor argument is a constant int literal? Just as in the main function? – Zebrafish Oct 14 '18 at 09:26
  • 1
    `int f(5);` is unambiguous, but there's not much reason to only permit `()` in the unambiguous cases. – T.C. Oct 14 '18 at 09:29
  • I see, except in functions it does allow it in unambiguous cases. Anyway, I don't want to draw this out unnecessarily, I guess it's just a rule disallowing this with class members. Thanks. – Zebrafish Oct 14 '18 at 09:33