Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Clang error: calling a private constructor while none of them were actually called

I made a static function of some class, and made constructor private. Now I want to use the function. Clang++ says "The constructor is private", while g++ compiles normally.

The thing is, I don’t know if there are any rules in any Standard which could affect this in any way. Any function can make a variable and there is no way it couldn’t return a value. So there should be no errors with MyStruct::make in the code above, right? But Clang feels differently about that.
So, the question is, is this what Clang should make doable or is this that sort of thing that should never be done in C++?

I’ve tried to make C++ be a little more like Rust here, so that I could never do something unexpected with constructors. I used g++ and the following code works.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#include <iostream>
#include <optional>
#include <utility>

class MyStruct {
public:
  static auto make(int val) -> MyStruct {
    MyStruct that(val);
    return that;
  };

  auto copy() -> MyStruct {
    MyStruct copy(this->val);
    return copy;
  }

  auto value() -> int { return this->val; }

private:
  MyStruct() = delete;

  MyStruct(int val) { this->val = val; }

  MyStruct(const MyStruct &other) { this->val = other.val; }

  int val;
};

auto main() -> int {
  auto my_struct = MyStruct::make(4);

  auto my_new_struct = my_struct.copy();

  std::cout << my_new_struct.value();
  std::cout << MyStruct::make(7).value();
}

With Clang, however, I’ve encountered some errors:

main.cpp:30:20: error: calling a private constructor of class 'MyStruct'
  auto my_struct = MyStruct::make(4);
                   ^
main.cpp:24:3: note: declared private here
  MyStruct(const MyStruct &other) { this->val = other.val; }
  ^
main.cpp:32:24: error: calling a private constructor of class 'MyStruct'
  auto my_new_struct = my_struct.copy();
                       ^
main.cpp:24:3: note: declared private here
  MyStruct(const MyStruct &other) { this->val = other.val; }
  ^
2 errors generated.

So, another time, the question is, is this what Clang should make doable or is this that sort of thing that should never be done in C++, and why?

>Solution :

Formally for example in this line

auto my_struct = MyStruct::make(4);

there should be used the copy construtor if not take into account the copy/move elision.

Before the C++ 17 Standard the copy constructor shall be acceptable even if its call is elided.

From the C++ 14 Standard( 12.8 Copying and moving class objects)

  1. … [Note: This two-stage overload resolution must be performed regardless of whether copy elision will occur. It determines the
    constructor to be called if elision is not performed, and the
    selected constructor must be accessible even if the call is elided
    .
    end note ]

Either make the copy constructor public or switch on the support of at least the C++ 17 Standard.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading