Suppose you have a class called Product, defined like this:
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 a variable like this:
auto p = Product{"abc",123};
I thought that the standard dictated that a compiler must logically do the following:
- construct a temporary Product
- move-construct p (using the temporary Product)
But that the compiler was allowed to optimize this so that p is directly constructed.
I verified this (Visual Studio 2013) and indeed, the compiler optimizes this, even if we have our own custom (non-default) move-constructor. This is fine.
However, if I explicitly delete the copy- and move-constructor, like this:
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;
};
The auto+brace initialization still compiles. I though the compiler had to prevent this because there is no copy- or move- allowed.
Strange enough, if I make the deleted copy- and move-constructor private, 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 the auto+brace initialization doesn't compiler anymore.
error C2248: 'Product::Product' : cannot access private member declared in class 'Product'
Is this expected behavior? Is this a bug in Visual Studio 2013 (Update 3)?
Note: I tried compiling this on ideone and there it indeed refuses to compile the initialization when the copy- and move-constructors are deleted (and public). So I think this is a Visual Studio bug.