1

I have defined class A as follows.

#include <cstring>
#include <utility>
class A
{
  private:
  int        *pa_;
  std::size_t size_;

  public:
  explicit A(std::size_t size)
      : pa_{new int[size]}, size_{size} {};

  // copy constructor
  A(const A &other)
      : pa_{new int[other.size_]}, size_{other.size_}
  {
    std::memcpy(pa_, other.pa_, size_);
  }

  // move constructor
  A(A &&other)
      : pa_{other.pa_}, size_{other.size_}
  {
    other.pa_ = nullptr;
  }
};

I have tried several copy/move constructor calls.

int main(int argc, char const *argv[])
{
  A a1{100};    // ok
  A(a1);        // error
  A a2 = A(a1); // ok
  A{a1};        // ok
  A aa[] = {    // ok
            A(a1),
            A(a1)};
  A(std::move(a1)); // ok
}

The following error occurs.

>  g++-11 -std=c++17 -Wall -pedantic-errors -fdiagnostics-color=always example.cpp
example.cpp: In function 'int main(int, const char**)':
example.cpp:30:4: warning: unnecessary parentheses in declaration of 'a1' [-Wparentheses]
   30 |   A(a1);        // error
      |    ^~~~
example.cpp:30:4: note: remove parentheses
   30 |   A(a1);        // error
      |    ^~~~
      |    -  -
example.cpp:30:5: error: redeclaration of 'A a1'
   30 |   A(a1);        // error
      |     ^~
example.cpp:29:5: note: 'A a1' previously declared here
   29 |   A a1{100};    // ok
      |     ^~
example.cpp:33:5: warning: unused variable 'aa' [-Wunused-variable]
   33 |   A aa[] = {    // ok
      |     ^~

Why does a copy constructor call using parentheses result in a compile error?

Is this a problem that cannot be solved?

I don't know if I actually need to use this syntax, but the behavior is counter-intuitive.

ph3
  • 21
  • 2
  • 5
    What error do you get? – NathanOliver Jun 15 '22 at 03:18
  • isnt this an example of 'the most infuriating parse' – pm100 Jun 15 '22 at 03:25
  • Yeah, `type(name)` is parsed as declaring a variable of type `type` and name `name`. – NathanOliver Jun 15 '22 at 03:26
  • 1
    @Tas This isn't an example of the most vexing parse. The declaration unambiguously declares a variable, it's just that the parentheses are unnecessary. – cigien Jun 15 '22 at 04:22
  • Your compiler seems to have explained the situation fairly clearly. The first warning tells you that the thing you wanted to be copy-construction is in fact a variable declaration, specifically of `a1`. The first note clarifies this by indicating that removing the parentheses will not change the meaning of that line, and the result of removing the parentheses -- `A a1;` -- certainly does not look like copy construction. Then the error reinforces that line 30 is a declaration of `a1`, not copy construction, by stating that `a1` is declared on both lines 30 and 29. – JaMiT Jun 15 '22 at 06:12
  • @Tas Oops, I should have done that already. It's done now, thanks for the ping. – cigien Jun 15 '22 at 16:27

0 Answers0