I have a snippet:
struct MyCass2 {
MyCass2() {}
MyCass2(MyCass2 const&) = delete;
MyCass2(MyCass2&&) = delete;
};
int
main() {
auto a = MyCass2();
}
This results in
main.cpp:43:8: error: call to deleted constructor of 'MyCass2'
auto a = MyCass2();
^ ~~~~~~~~~
main.cpp:38:3: note: 'MyCass2' has been explicitly marked deleted here
MyCass2(MyCass2&&) = delete;
^
1 error generated.
Why I thought there will be a template type deduction and a direct initialization after all? Can somebody explain how the automatic variable initialization work in this case?
Why I thought there will be a template type deduction
auto uses the rules of template argument deduction to deduce the type of the variable. In this case, the type will be deduced to be MyCass2.
and a direct initialization after all?
a is not direct-initialized, because you used copy-initialization - see the syntax labeled (1).
how the automatic variable initialization work in this case?
a is copy-initialized from the temporary on the right hand side of =. However, since the type is neither copyable, nor movable, the copy initialization is not allowed.
But I [defined] the move/copy constructors and neither of them was called, how is that?
The default constructor was used to initialize the temporary. The call to the move constructor in the copy initialization is allowed to be elided.
I was sure that this auto var=initializer is kind of a syntax overloading. Like with copy initialization T var=initializer, where instead of operator= a copy constructor is called.
Well, it isn't. Here, auto is used for, and only for deducing the type. Once the type has been deduced, the expression is entirely equivalent to
MyCass2 a = MyCass2();
auto a = MyCass2();
Uses copy/move initialization. Now since you have a have a move constructor declared (yes a deleted function is still a declared function) the compiler going to try and use that to move the temporary into a as it is the best match. When it goes to do that though it tries to use the deleted move constructor. Trying to use a deleted function is ill formed and the compiler generates an error.
If you want to allow the above code you work you need to have either the copy or move constructor defined. Do note that in a case like
auto a = some_named_myclass2_object;
The copy constructor needs to be defined as some_named_myclass2_object is an lvalue and cannot be moved from without std::move
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