2013-04-30 2 views
84
class A {}; 

int main() { 
A() = A(); 
return 0; 
} 

Почему этот код скомпилирован? Должна ли быть некоторая ошибка, которая на левой стороне оператора присваивания должна быть установлена ​​lvalue? Является ли A() lvalue? g ++ 4.7 версияA() = A() - зачем он компилируется?

ответ

87

Для встроенных типов вы должны быть правы: для встроенного оператора присваивания требуется модифицируемая lvalue с левой стороны.

Однако это не использование встроенного оператора, а перегрузка, которая неявно объявлена ​​классом. Это функция член, эквивалентный

A().operator=(A()); 

и членов функций можно назвать на rvalues ​​.

+0

Это не использование A (A())? – stardust

+7

не инициализация копирования? – stardust

+0

@Named его вызов 'operator =' на A –

32

Если вы действительно хотите, вы можете сделать это не компилируется с C++ 11:

class A { 
    template <typename T> 
    void operator=(T&&) && = delete; // no op= for rvalues 

    // generate other special members normally 
    A() = default; 
    A(A const&) = default; 
    A(A&&) = default; 
    ~A() = default; 
    // op= only for lvalues 
    A& operator=(A&&) & = default; 
    A& operator=(A const&) & = default; 
}; 

int main() { 
A() = A(); // error 
return 0; 
} 

(live example)

Обратите внимание на & и && (он же реф-классификаторов) в конце декларации различных форм operator=. Это позволяет отображать эти объявления для lvalues ​​и rvalues ​​соответственно. Тем не менее, версия rvalue, когда она выбрана с помощью разрешения перегрузки, приводит к плохому формированию программы, поскольку она удалена.

Порожденный по умолчанию оператор =, однако, не имеет никакого ref-определителя, то есть он может быть вызван как для lvalues, так и для rvalues; поэтому код в вопросе компилируется, хотя A() является rvalue.

1

Компилятор C++ предоставляет все классы конструктору по умолчанию, это то, что происходит в отношении вашего кода, когда вы говорите A() = A(); он просто вызывает конструктор с безымянным объектом, и функция возвращает ссылку на построенный объект (неявный). Вот и все ...

Смежные вопросы