Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between not implementing and deleting common operators?

Tags:

c++

c++11

Let's say I have a class

class Object
{
public:
    Object(int i) : num(i) {};

    int getNum() const { return num; }
private:
    int num;
};

Now, if I try to do this

Object obj{ 1 };
Object obj2{ 2 };
Object obj3 = obj + obj2; //This is wrong

This is illegal: 'Object' does not define this operator or a conversion to a type acceptable to the predefined operator.

Adding Object operator+(const Object&) = delete; doesn't really change anything, except for the error message: 'Object Object::operator +(const Object &)': attempting to reference a deleted function.

Is the delete only needed for operators that have an implicit declaration (like assignment operator and copy/move constructor) or does it change anything else in my case?

like image 339
Rakete1111 Avatar asked Mar 27 '16 02:03

Rakete1111


People also ask

Whats the difference between delete and delete []?

delete is used for one single pointer and delete[] is used for deleting an array through a pointer. This might help you to understand better.

What is a delete operator?

The delete operator removes a given property from an object. On successful deletion, it will return true , else false will be returned.

What is the difference between delete and delete function in C Plus Plus?

What is the difference between delete and delete[] in C++? Explanation: delete is used to delete a single object initiated using new keyword whereas delete[] is used to delete a group of objects initiated with the new operator. 4.

What does delete keyword do when applied on a function declaration?

Using the delete operator on an object deallocates its memory.


2 Answers

Is the delete only needed for operators that have an implicit declaration (like assignment operator and copy/move constructor) or does it change anything else in my case?

No and no. Your case is merely too simple for any such difference to matter.

= delete serves two purposes:

1: It forcibly removes functions which would (potentially) otherwise be there. Namely, the special member functions.

2: It specifies that a function with that signature cannot be called. This is essentially a generalization of #1.

The archetypal example of the latter is for preventing implicit conversion of function arguments. If you do this:

void foo(float val);
void foo(int) = delete;

You can no longer call foo(5); you must use foo(5.f). Why? Because the compiler will see the second overload, see that it matches the call the best, and then immediately fail because the function is deleted.

This is sometimes done like this as well:

void foo(float val);
template<typename T> void foo(T&&) = delete;

This ensures that you can only call it with an actual float. No type which is implicitly convertible from float will work.

like image 72
Nicol Bolas Avatar answered Oct 25 '22 19:10

Nicol Bolas


The anwer by @NicolBolas is perfectly acceptable. Here's another example to illustrate that sometimes it's not enough not to declare/define a function because someone else does (such as the compiler generated special member functions) and your code can call it (e.g. through implicit constructors or conversion operators).

#include <iostream>

// your code
struct Base {};

// some teammate
struct Wrap
{
    /* implicit */ Wrap(Base const& b) {}
};

void fun(Wrap const&) { std::cout << __PRETTY_FUNCTION__ << '\n'; }

// client code
int main()
{
    Base b;
    fun(b); // oops, probably didn't intend to call fun(Wrap const&)
}

Live Example that outputs void fun(const Wrap &).

Now in the old days pre-C++11, you could declare but not define

void fun(Base const&); // no definition provided

Live Example that outputs the linker error

main.cpp:(.text+0x36): undefined reference to 'fun(Base const&)'

From C++11 onwards, you can explicitly delete the same function

void fun(Base const&) = delete; // C++11 onwards

Live Example that outputs the compiler error (which is much more informative than the previous linker error)

main.cpp:20:5: error: call to deleted function 'fun'
    fun(b); // oops, probably didn't intend to call fun(Wrap const&)
    ^~~
main.cpp:6:6: note: candidate function has been explicitly deleted
void fun(Base const&) = delete; // C++11 onwards
     ^
like image 27
TemplateRex Avatar answered Oct 25 '22 20:10

TemplateRex