Reputation: 143
In the following simplification of a real-world example, the intention is to enforce that a user of class A
can only obtain temporary references to its objects (in my actual example, the class A
is a proxy class used to overload operators on the return values of other classes):
struct A {
static A foo() {
return A();
}
private:
A() {}
A(const A&) = default;
};
int main() {
A a = A::foo();
}
I therefore expect the assignment to a
to fail, and this is indeed what happens in C++14 and earlier:
main.cpp:11:11: error: calling a private constructor of class 'A'
A a = A::foo();
^
main.cpp:7:5: note: declared private here
A(const A&) = default;
^
However, in C++17, this is not an error since, because there is no assignment happening, rather a
is merely being copy initialized. In this case, how can I enforce the previous semantics? Is there a way to declare copy initialization of A
to be private as well (preferably without modifying the return type of foo)?
Upvotes: 0
Views: 107
Reputation: 473447
You cannot. The entire point of guaranteed elision is to make it so that A a = A::foo();
doesn't do any copying. Ever. Even hypothetically. And the point of that is to be able to have factory functions even for types that cannot be copied/moved.
C++17 and above do not allow you the power to deny someone the ability to use a factory function for your type, so long as their code complies with the rules of guaranteed elision.
Upvotes: 3