Consider the following class:
template <class T>
class object {
public:
using type = T;
object() = delete;
object(const object&) = delete;
object(object&&) = delete;
object& operator=(const object&) = delete;
object& operator=(object&&) = delete;
~object() = delete;
private:
type value = 0;
};
Is it possible to instantiate an object (on the stack (probably not) or on the heap (maybe?)) of type object<int>
by any weird trickery, or is it impossible for an object<int>
to ever exist in any conceivable (well formed and with well defined behavior) C++17
program?
Addendum: First we consider non ill-formed NDR programs/non undefined behavior. If and only if, there are only ill-formed NDR programs/undefined behavior programs possible, you can illustrate the answer with such a program.
No it cannot. From [basic.life]
[...] The lifetime of an object of type
T
begins when:
storage with the proper alignment and size for type
T
is obtained, andif the object has non-vacuous initialization, its initialization is complete,
Thus initialization must be performed. We then look at all the possible initializations.
If the initializer is {...}
, then it is list-initialized.
{}
{x}
, which calls a constructor through overload resolutionIf the initializer is ()
, then it is value-initialized
If the initializer is the same cv-unqualified type, the initializer expression for the initializer is used instead as the initializer
T x = T(T());
is just to default-initialize x
, with no copiesIf there is no initializers, then it is default-initialized
Otherwise constructors are considered and called with overload resolution.
To value-initialize is to default-initialize the object in this case.
Default-initialization calls the default constructor in this case.
If you look carefully, there is only one way on this list to initialize the object, and that is to call a constructor. Since we have deleted all constructors, we can't initialize the object.
I don't claim this to be an answer (am not a language lawyer), just post some findings from n4659:
11.6.20: An object whose initialization has completed is deemed to be constructed, even if no constructor of the object’s class is invoked for the initialization. [ Note: Such an object might have been value-initialized or initialized by aggregate initialization (11.6.1) or by an inherited constructor (15.6.3). —end note ]
From the 3 options mentioned in the note, only the first applies:
11.6.8: To value-initialize an object of type T means ... (8.1) — if T is a (possibly cv-qualified) class type (Clause 12) with either no default constructor (15.1) or a default constructor that is user-provided or deleted, then the object is default-initialized;
Since a default constructor is deleted:
11.6.7: To default-initialize an object of type T means ... (7.1) — If T is a (possibly cv-qualified) class type (Clause 12), constructors are considered. The applicable constructors are enumerated (16.3.1.3), and the best one for the initializer () is chosen through overload resolution (16.3). The constructor thus selected is called, with an empty argument list, to initialize the object.
Since there is no constructor that can be called, I think the instance of class object
cannot be constructed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With