5

Here is an example I wrote up:

struct Foo
{
  Foo() = default;
  Foo(int)
  {

  };
};

int main()
{
  int baz = 10;
  Foo(1); // OK
  Foo(baz); // Fails, redefinition 
  return 0;
}

Why does Foo(baz) try construct a new object baz, rather than constructing an anonymous object passing an argument baz to the constructor? When I declare an object bar by writing Foo(bar), I get a default initialized object just fine, but once I try passing a argument, it fails. How is the ambiguity resolved?

Krystian S
  • 1,586
  • 7
  • 23
  • 2
    If it could be a declaration, it is a declaration. – melpomene Nov 04 '18 at 23:00
  • @melpomene why it can't be a declaration with a literal, but it can be a declaration with a variable (without a type)? – Yksisarvinen Nov 04 '18 at 23:02
  • 1
    What do you mean, without a type? `Foo` is a type. It can't be a declaration with `1` because `1` is not a valid variable name. – melpomene Nov 04 '18 at 23:03
  • I assume this is related to the most vexing parse. But not how I have seen it manifest before. I suppose `baz` must be seen as an undeclared type...? I don't know why that would be though. – Galik Nov 04 '18 at 23:06
  • 1
    Ooh, I thought that it's actually most vexing parse problem, but it's just a variable name reuse? Sorry for the confusion. – Yksisarvinen Nov 04 '18 at 23:06

1 Answers1

5

Foo(baz); is equivalent to Foo baz; which is obviously a declaration.

And as baz was already declared as a local variable of type int earlier in the same scope, you get a redefinition-error.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • This is evidently correct but I still don't see why declarations like that are allowed. Do you know if there is any use for that kind of declaration? – Galik Nov 04 '18 at 23:09
  • @Galik Mix pointers, functions, and arrays, stir rigorously, and you might need parentheses for overriding the natural grouping. For simple declarations, yes, it obviously only leads to Irritation. – Deduplicator Nov 04 '18 at 23:12
  • 1
    @Galik This specific form? No, but declarators are parsed like expressions and you need the parens e.g. in `int (*ptr)[10];`. It's just that `int (*ptr);` and `int (i);` are also valid. – melpomene Nov 04 '18 at 23:12
  • @Galik: it's probably tied to how parenthesis are tied to complex declarations: [`int (*(*foo)(char))(short)`](https://cdecl.org/?q=int+%28*%28*foo%29%28char%29%29%28short%29) – Mooing Duck Nov 04 '18 at 23:13
  • @Deduplicator Of course. It is easier to allow this to facilitate the "right-left" rule of determining types. This is what it boils down to at the simplest level. – Galik Nov 04 '18 at 23:13