Невозможно использовать конструктор класса, используя нотацию равенства, когда конструктор копирования класса удален - PullRequest
0 голосов
/ 01 июня 2019

При тестировании некоторых классов я сталкиваюсь с интересной проблемой: при вызове конструктора класса с использованием нотации равенства (=), если конструктор копирования удален, возникает ошибка ошибка: копирование переменной типа 'Class' вызывает удалениеконструктор .При использовании круглых скобок код компилируется нормально.

Что здесь происходит?Может ли это быть ошибкой компилятора?

Рассмотрим следующий класс:

class Test
{
    public:
        int Int;

    public:
        Test() = default;
        Test(Test &) = delete;
        Test(Test &&) = delete;
        Test(int i)
        {
            Int = i;
        }
};

Конструкторы вызываются так:

Test t1(3);  //No error
Test t2 = 3; //error: copying variable of type 'Class' invokes deleted constructor

Просто для проверки я пыталсядобавьте некоторые проверки и разрешите эти функции и скомпилируйте код.Оба конструктора скомпилировали , используя MSVC точно таким же образом .

class Test
{
    public:
        int Int;

    public:
        Test()
        {
            Int = 0;
            cout << "Constructor";
        }
        Test(Test &t)
        {
            Int = t.Int;
            cout << "Copy Constructor";
        }
        Test(Test &&t)
        {
            Int = t.Int;
            cout << "Move Constructor";
        }
        Test(int i)
        {
            Int = i;
            cout << "Constructor from int";
        }
};
Test t1(3);  //Constructor from int
Test t2 = 3; //Constructor from int

Что именно здесь происходит?

1 Ответ

1 голос
/ 01 июня 2019

Вы видите результаты правила copy elision .

По сути, говоря, что T var = expr; создает безымянный темп из expr, а затем копирует или перемещает его в var используя копию или переместить конструктора.Если конструкторы копирования и перемещения удалены, то это дает ошибку об удаленном конструкторе.Но тогда компилятору требуется , чтобы исключить это копирование или перемещение и создать var непосредственно из expr, даже если конструктор копирования или перемещения имеет видимые побочные эффекты.Это один из тех странных угловых случаев, которые возникают из-за языкового проектирования путем фактической стандартизации того, что делают (или делали в прошлом) разрозненные реализации, плюс поэтапного проектирования и медленной эволюции с течением времени, пытаясь сохранить обратную совместимость..

см. Здесь для дальнейшего обсуждения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...