Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

attempting to reference a deleted function when passing by reference with a const member

Tags:

c++

I'm clearly missing something out.

If I have:

class MyClass
{
public:
    const int something;

    MyClass(int Something) : something(something) {}
};

This will fail (attempting to reference a deleted function) because I have no copy constructor

std::vector<MyClass> myStuff;
std::sort(myStuff.begin(), myStuff.end(), 
    [](MyClass lhs, MyClass rhs) { 
        return lhs.something > rhs.something; });

So I should pass by reference. But I have the same problem even if the lambda becomes

[](const MyClass& lhs, const MyClass& rhs) { 
    return lhs.something > rhs.something; });

What's the reason behind this? The workaround is clear (don't have const member variables), but I want to know what I'm missing in the above example.

like image 530
icebp Avatar asked Jan 18 '26 02:01

icebp


1 Answers

Your class has a const member, while you are asking std::sort to basically swap instances of your class around. Unlike a Java ArrayList, which contains handles (garbage-collected pointers) to the objects, C++ STL containers directly contain the objects themselves. Thus, you cannot swap the instances around because that would mean overwriting a const object. Your solution will have to be one of the following:

  • Sort a vector of pointers or references to the objects: you can use vector<MyClass*> or vector<reference_wrapper<MyClass>> if you have the instances elsewhere, or vector<unique_ptr<MyClass>> if the vector owns the instances.
  • Make the field non-const. Then your class will have a copy assignment operator (and a move ctor/op=, but with only that member it would be identical)
  • Provide a custom move/copy op= that uses const_cast to cast away the const-ness of the field. This is a bad idea, since the standard says it is undefined behaviour (i.e. the compiler and program may set your computer aflame if they want to) under certain cases. I don't remember the exact standardese, but you would have to be very careful not to fall in one of the jolly C++ undefined behaviour traps.
like image 77
Javier Martín Avatar answered Jan 20 '26 17:01

Javier Martín



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!