Issue
I have the following code in VS2019 (haven't tested with other compilers yet).
class A
{
// A should be a pure virtual class
};
class B
{
const A* member;
public:
B(const A& arg) : member{ &arg } {}
// Solves the problem
// B(const A&& arg) = delete;
void setA(const A& arg) { member = &arg; }
// Solves the problem
// setA(const A&& arg) = delete;
void setA(const A& arg) { member = &arg; }
};
int main()
{
B b(A{});
b.setA( A{} );
return 0;
}
Now, the behavior in set function is what's expected - it doesn't accept an rvalue. On the other way, constructor happily accepts the an rvalue without warning or compiler errors. As I see it, the compiler assumes copy semantics in case of constructor, but correctly resolves it in the second case. This behavior does not occur if I pass A& instead of const A&
Is there a way to force the compiler not accept rvalues in the constructor? A one way to solve that was to delete the B(const A&&) constructor. Is there a more elegant way / uniform way to do it? Making constructor explicit still does not solve the problem.
Edit - the suggested link doesn't answer my question. As the solution suggested there (namely explicitly deleting const rvalue reference) was already mentioned in my question. I was asking whether there exists another way except explicitly deleting the overload. I am also trying to understand whether it is a bug (in the compiler or the standard) or it's the way it should be.
Solution
In case of constructor, deleting is not only most elegant, but a recommended method ( rule of five - rule of zero).
b.setA( A{} );
would accept both rvalue reference and general reference.
B b(A{});
A a;
b.setA( a );
To avoid this you have to use delete overloaded version:
void setA(const A&& arg) = delete;
Answered By - Swift - Friday Pie Answer Checked By - Timothy Miller (PHPFixing Admin)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.