2016-07-23 2 views
3

У меня есть эта программа:двигаться назначаемые лямбды в лязгом и НКУ

int main() 
{ 
    auto l([](){}); 

    ::std::cout << ::std::is_move_assignable<decltype(l)>{} << ::std::endl; 
} 

GCC-6.1.1 отображает 0

лязгом-3.8.0 отображает 1

Это вызывает ошибку компиляции в моей программе. Какой из компиляторов прав?

Ошибка:

error: object of type '(lambda at t.cpp:5:5)' cannot be assigned because its copy assignment operator is implicitly deleted 

Но это не имеет отношения к моему вопросу.

+0

Покажите ошибку, которую вы получите. –

ответ

-1

A lambda с пустым списком захвата определяется как назначаемый для типа указателя функции, поэтому, если ваш фактический код имеет этот тип лямбда-функции, вы можете просто использовать указатель на функцию.

+1

не стесняйтесь записывать что-то в этом примере. – user1095108

+0

@ user1095108 Ну, ваш вопрос показал лямбду без захвата и спросил, должен ли _that_ быть переадресованным. Вам нужно подготовить MVCE для вопроса (в этом случае это будет так же просто, как наличие захваченной переменной). –

4

N4140 (примерно C++ 14) говорит:

5.1.2 Lambda expressions [expr.prim.lambda]

20 The closure type associated with a lambda-expression has a deleted (8.4.3) default constructor and a deleted copy assignment operator. It has an implicitly-declared copy constructor (12.8) and may have an implicitly-declared move constructor (12.8). [ Note: The copy/move constructor is implicitly defined in the same way as any other implicitly declared copy/move constructor would be implicitly defined. -- end note ]

Обратите внимание, что это не упоминается ли неявно объявляется удаленный оператор копирующего присваивания. Компилятор превращает лямбда в определение класса и экземпляр, но этот класс можно продуманно определить таким образом, что оператор назначения копирования неявно объявлен, но какое-либо другое свойство класса приводит к удалению этого оператора неявного копирования.

Тогда:

12.8 Copying and moving class objects [class.copy]

20 If the definition of a class X does not explicitly declare a move assignment operator, one will be implicitly declared as defaulted if and only if

(20.1) -- X does not have a user-declared copy constructor,

(20.2) -- X does not have a user-declared move constructor,

(20.3) -- X does not have a user-declared copy assignment operator, and

(20.4) -- X does not have a user-declared destructor.

Если оператор копирующего присваивания лямбда является неявно объявляется, он не ингибирует образование оператора присваивания шаг. Если он явно объявлен, оператор присваивания перемещения подавляется.

Оба вида поведения являются оправданными на основе буквальной формулировки стандарта.

Это был частично рассмотрен CWG issue 1891, которые изменили текст:

The closure type associated with a lambda-expression has no default constructor and a deleted copy assignment operator. It has a defaulted copy constructor and a defaulted move constructor (12.8 [class.copy]). [Note: These special member functions are implicitly defined as usual, and might therefore be defined as deleted. -- end note]

Однако, несмотря на то, оператор присваивания движения поднимаются как проблема в этом вопросе, это не меняет ответ, он по-прежнему чтобы открыть возможность.

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