лямбда — есть ли лучший способ реализации Java-подобный локальный класс в C ++?

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

гм .. например:

  1. Мне нужен объект, который захватывает локальные переменные и содержит более одной функции, которые, к сожалению, имеют одинаковую сигнатуру.

    • Перегрузка лямбды может решить эту проблему, если функции имеют разные сигнатуры. И я думаю, что это одна из распространенных проблем, поскольку существует лямбда-перегрузка.
  2. Мне нужен объект, который захватывает локальные переменные и наследует некоторый другой класс или имеет переменные-члены.

    • Это то, что происходит каждый день в мире Java. Динамический полиморфизм имеет свою полезность, по крайней мере, иногда.

Что я делаю сейчас, так это определяю некоторые вспомогательные макросы:

#define CAPTURE_VAL(Var) decltype(Var) Var
#define CAPTURE_REF(Var) decltype(Var) &Var
#define INIT_CAPTURE(Var) Var(Var)

И поместите их в местный класс:

struct Closure
{
Closure(CAPTURE_VAL(var1), CAPTURE_REF(var2)) : INIT_CAPTURE(var1), INIT_CAPTURE(var2)
{
}

int foo()
{
return some_expression;
}

private:

CAPTURE_VAL(var1);
CAPTURE_REF(var2);

} closure(var1, var2);

И это безобразно.

Я должен ссылаться на одну и ту же переменную три раза.

Я должен дать классу имя для ctor.

Я должен дать имя переменной для замыкания, хотя я думаю, что это не может помочь в соответствии с текущим стандартом.

По крайней мере, в VC ++ 11 захваченные переменные лямбды являются частными, поэтому я не могу просто наследовать класс лямбды. И для наследования лямбда-класса, по крайней мере, в VC ++ 11, нужна переменная (или, возможно, некоторые другие заполнители для оценки) для лямбда-выражения, что ужасно.


И я думаю, что даже не знаю, позволяет ли стандарт мне фиксировать тип локальных переменных в локальном классе таким образом …

Протестировано на GCC 4.6, тип локальной переменной не может быть перехвачен, как в VC ++. И захваченные переменные не выставляются как в VC ++. лол

Ах, мой плохой. Я забыл включить C ++ 11. Это прекрасно работает на G ++. Но лямбда-типы не могут быть унаследованы, а захваченные переменные по-прежнему не доступны.

Не совсем нормально … Придется оставить -пускание дальше. Или G ++ считает, что переменные-члены конфликтуют с локальными переменными, используемыми в decltype ().


Я бродил, почему C ++ выбрал такую ​​лямбду с высоким уровнем для закрытия вместо более общего локального класса, который может захватывать локальные переменные.

3

Решение

Это будет больше, чем просто комментарий к вашему вопросу, поэтому я сделаю ответ.

Есть действительно случаи, когда вы хотите что-то еще и более сложное, чем простой функтор или лямбда. Но эти случаи очень разные и разнообразные, не существует единого решения, особенно такого, которое укладывается в несколько строк и не затрагивает область действия одной функции.
Локальное создание сложного поведения внутри функции не является хорошей идеей с точки зрения читабельности и простоты, и, скорее всего, будет нарушать SRP для функции.
Во многих случаях, если вам нужно написать более одного operator()это означает, что вы захотите повторно использовать написанный код, что невозможно сделать, если он находится внутри локального класса.

Значение: в большинстве случаев будет лучшим решением написать правильный класс, вне функции, с правильными конструкторами и так далее.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]