Почему изменяемая лямбда с указателем на функцию-член? - PullRequest
3 голосов
/ 30 июля 2011

Я бы хотел получить свои грязные лапы на operator() лямбда-функции.Похоже, что задача выглядит следующим образом:

template <typename F>
void bar(F func) {
  void (F ::*pm)();
  pm = &F::operator();
}

Однако в следующем мне нужно включить ключевое слово mutable.Это почему?Можно ли выше вместо этого объявить указатель на функцию-член, которая может предназначаться для произвольных лямбд?

int main(int argc, char *argv[])
{
  bar([]() mutable {});
  return 0;
}

Ответы [ 3 ]

8 голосов
/ 30 июля 2011

Согласно 5.1.2 спецификации N3291 C ++ 0x, лямбда-оператор () равен const, если вы явно не объявите его mutable:

Этот оператор вызова функции объявляется const (9.3.1) тогда и только тогда, когда За параметром-объявлением-выражением выражения не следует mutable.

Вы можете использовать магию метапрограммирования шаблонов, чтобы определить, что есть что.

Однако следует отметить, что, как только func выходит из области видимости, вы больше не можете использовать этот указатель на член. И это указатель на член, а не указатель на функцию, поэтому вы не можете конвертировать между ними.

4 голосов
/ 30 июля 2011

C ++ 0x лямбды по умолчанию являются константными, в отличие от остального языка.Следовательно, ваша переменная-член-функция также должна быть константой.Должно работать следующее:

template<typename F>
void bar(F func) {
    typedef void (F::*pm_t)() const;
    pm_t pm = &F::operator();
}
1 голос
/ 30 июля 2011

Учтите это:

int x=0;
auto show = [x]() mutable
{
        x++;
};

show();

Перехватывается переменная 'x' по значению , и без mutable вы не можете изменять локальную копию этой переменной.Укажите mutable, чтобы разрешить изменение этой локальной копии.Для захватов по значению не имеет значения, если значение изменено, исходная переменная x не будет изменена.

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