Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best style for deleting all constructors (or other function)?

Let's say I want to make a type that cannot be constructed (don't ask why).

struct Impossible
{

I could do it like this:

    Impossible() = delete;
    // disable automatically generated constructors, don't declare any others
    Impossible(const Impossible&) = delete;
    // I suppose this is redundant with nothing to copy

or like this:

    Impossible(...) = delete;
    // explicitly disable all constructors

or like this:

    template<typename... Ts>
    Impossible(Ts...) = delete;
    // explicitly disable all constructors, template version
};

I guess I could ask the same thing about any function, not just constructors.

Does it make any difference which one I choose? In terms of syntax I think I like the second option. But is there any situation, whatsoever, where it's possible to detect a difference (other than in the text of an error message)?

like image 996
glaebhoerl Avatar asked Jan 03 '13 11:01

glaebhoerl


People also ask

What is the use of delete operator in C++?

The C++ 11 standard introduced another use of this operator, which is: To disable the usage of a member function. This is done by appending the =delete; specifier to the end of that function declaration. Any member function whose usage has been disabled by using the ‘=delete’ specifier is known as an explicitly deleted function.

Is there a default constructor for noncopyable?

You have to explicitly define the default constructor if you want one, even if it does nothing. Even if the explicitly-defined default constructor does nothing, it's considered non-trivial by the compiler. It's less efficient than an automatically generated default constructor and prevents noncopyable from being a true POD type.

Can a class have a default constructor with no parameters?

For example, if for any reason a base class fails to have a default constructor that's callable from a deriving class—that is, a public or protected constructor that takes no parameters—then a class that derives from it cannot automatically generate its own default constructor.

How do I delete a function in C++?

A better way to resolve the issue is to use the “delete” keyword (introduced in C++11) to delete the function: When a function has been deleted, any use of that function is considered a compile error. Note that the copy constructor and overloaded operators may also be deleted in order to prevent those functions from being used.


2 Answers

The first one is more than enough - no constructors will be generated by the compiler and, most imporatantly, it's idiomatic.

like image 181
Luchian Grigore Avatar answered Oct 02 '22 03:10

Luchian Grigore


There is a difference, for example:

#include <type_traits>

struct Unconstructible
{
    Unconstructible() = delete;
};

static_assert( !std::is_default_constructible<Unconstructible>::value, "not default constructible" );
static_assert( std::is_copy_constructible<Unconstructible>::value, "copyable" );

Although you can never construct this object, so in practice you can never create a copy of one either, according the language and the type traits in the library, it is technically CopyConstructible, because there's an implicitly-declared copy constructor.

Similarly, with the Impossible(...) or Impossible(Ts&&...) forms there is still an implicitly-declared copy constructor.

On the other hand, if you do it this way:

#include <type_traits>

struct Unconstructible
{
    Unconstructible(const Unconstructible&) = delete;
};

static_assert( !std::is_default_constructible<Unconstructible>::value, "not default constructible" );
static_assert( !std::is_copy_constructible<Unconstructible>::value, "not copyable" );

The existence of a user-declared constructor suppresses the implicit declaration of the default constructor, so the class is neither DefaultConstructible nor CopyConstructible.


N.B. your last example should probably be Impossible(Ts&&...) to match any types, including non-copyable and non-movable ones.

like image 23
Jonathan Wakely Avatar answered Oct 02 '22 04:10

Jonathan Wakely