2

I have come across an unusual syntax in a C++ class at work. (It is valid and godbolt will compile it.)

The assignment operators use a trailing ampersand before specifying the functions that should be deleted. Removing the ampersands seems to result in the same behavior.

What do the ampersands do?

#include <memory>

class CustomClass
{
public:
    CustomClass() = default;
    virtual ~CustomClass() = default;
    CustomClass(const CustomClass&) = delete;
    CustomClass(CustomClass&&) = delete;

    CustomClass& operator=(const CustomClass&) & = delete;
    // What is this ---------------------------^

    CustomClass& operator=(CustomClass&&) & = delete;
    // What is this ----------------------^
};


int main()
{
    CustomClass cc{};
    CustomClass cc2{};
    cc = cc2;            // Error: Use of operator=(const CustomClass&)
    cc = std::move(cc2); // Error: Use of operator=(CustomClass&&)

    return 0;
}
LeviX
  • 3,096
  • 3
  • 28
  • 41
  • 1
    This is a function [ref-qualifier](https://en.cppreference.com/w/cpp/language/member_functions#member_functions_with_ref-qualifier), making the function callable only on lvalues. `&&` can be used to only allow rvalues. I don't think it does anything in this specific case, the author probably writes them on all assignment operators by default to prevent things like `CustomClass{} = ...;`. – HolyBlackCat Nov 09 '22 at 19:01
  • 2
    i remember reading up on this and thinking "perhaps we have gone too far with syntax" – Neil Butterworth Nov 09 '22 at 19:07
  • 2
    @NeilButterworth: [That's why we have this.](https://en.cppreference.com/w/cpp/language/member_functions#Explicit_object_parameter) – Nicol Bolas Nov 09 '22 at 19:11
  • 1
    @Nicol my problem is not so much with the concept as the syntax - how many ampersands can a person take? – Neil Butterworth Nov 09 '22 at 19:17
  • In this case declaring the assignment operators as deleted with an lvalue on the left hand side also deletes them when an rvalue is on the left hand side because any user-declared assignment operator inhibits the automatic generation of any other assignment operator. But in general you can use this to have functions that are callable from lvalues but not rvalues, or functions whose implementations differ based on the value category of the object. – Nathan Pierson Nov 09 '22 at 19:17
  • @HolyBlackCat I think it can only do something if there is another declaration with `&&`, as in `CustomClass& operator=(const CustomClass&) && = default;` – Nelfeal Nov 09 '22 at 19:18
  • @NeilButterworth: "*how many ampersands can a person take?*" As many as you need to say what you need to say. Just as with any syntax. – Nicol Bolas Nov 09 '22 at 20:12
  • The more I learn about C++ the less I know. – LeviX Nov 10 '22 at 20:55

0 Answers0