Suppose you have a class called Product, defined as follows:
class Product { public: Product(const char *name, int i); Product(Product &&rhs); Product(const Product &rhs); ~Product(); private: const char *m_name; int m_i; };
and you initialize the variable as follows:
auto p = Product{"abc",123};
I thought the standard dictates that the compiler should logically do the following:
- create a temporary product
- move-construct p (using a temporary product)
But the compiler was allowed to optimize it so that p was built directly.
I checked this (Visual Studio 2013), and indeed, the compiler optimizes this, even if we have our own custom (non-standard) move-constructor. This is normal.
However, if I explicitly remove the copy and move constructor, for example:
class Product { public: Product(const char *name, int i); Product(Product &&rhs) = delete; Product(const Product &rhs) = delete; ~Product(); private: const char *m_name; int m_i; };
Auto + brace initialization is still compiling. I, although the compiler should have prevented this, because copying or moving is not allowed.
It is strange if I make a private instance of private-copy-move-move, like this:
class Product { public: Product(const char *name, int i); ~Product(); private: Product(Product &&rhs) = delete; Product(const Product &rhs) = delete; const char *m_name; int m_i; };
Then auto + brace initialization is no longer a compiler.
error C2248: 'Product::Product' : cannot access private member declared in class 'Product'
Is this the expected behavior? Is this a bug in Visual Studio 2013 (Update 3)?
Note: I tried to compile this on ideone , and there it really refuses to compile initialization when copies and move-constructors are deleted (and publicly accessible), so I think this is a Visual Studio error.