Załóżmy, że masz klasę o nazwie produktu, zdefiniowane następująco:Kiedy można kompilować optymalizację inicjowania stylu auto + brace?
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;
};
i zainicjować zmienną tak:
auto p = Product{"abc",123};
Myślałem, że średnia podyktowane że kompilator musi logicznie wykonaj następujące czynności :
- konstrukcją tymczasową produktu
- ruch konstrukt P (przy użyciu tymczasowy produkt)
Ale kompilator mógł to zoptymalizować, aby p było konstruowane bezpośrednio.
I zweryfikowane to (Visual Studio 2013) i rzeczywiście, kompilator optymalizuje ten, nawet jeśli mamy własną niestandardową (inny niż domyślny) move-konstruktor. Jest okej.
Jednakże, jeśli jawnie usunąć i przenieść kopiowaniem-konstruktora, na przykład:
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 + klamra inicjalizacji nadal kompiluje. Chociaż kompilator musiał temu zapobiec, ponieważ nie było dozwolonego kopiowania ani przenoszenia.
tyle dziwne, jeśli robię usuniętego przed kopiowaniem i przenieść-konstruktora prywatnych, jak poniżej:
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;
};
Następnie inicjalizacji auto + klamra nie kompilator już.
error C2248: 'Product::Product' : cannot access private member declared in class 'Product'
Czy to oczekiwane zachowanie? Czy to błąd w Visual Studio 2013 (aktualizacja 3)?
Uwaga: Uwaga: Próbowałem skompilować to na ideone i tam rzeczywiście odmawia kompilacji inicjowania, gdy konstruktorzy kopiowania i przenoszenia są usuwane (i publiczne). Więc myślę, że to błąd Visual Studio.
Wystarczy FYI w Visual Studio 2013, * kompilator generowane * konstruktorzy coraz szerzej operatory przypisania są obsługiwane ** ** nie (choć można definiować własne). [Tutaj znajduje się lista C++ 11 VS2013 (non)) (https://msdn.microsoft.com/en-us/library/hh567368.aspx#featurelist) – CoryKramer
Wersja kompilatora 18.00.30723. Czy ten błąd można wprowadzić między 21005 a 30723? – Patrick
@ Patricka NVM. Raz podałem puste nawiasy dla konstruktora i destruktora skompilowanego na VS. – NathanOliver