Использование объявления указателя функции в качестве объявления lamba - PullRequest
0 голосов
/ 27 сентября 2018

Что мне ближе всего к этому?.

.h:
    typedef bool (*DoWorkFunc)(uint32_t dParam1, uint32_t dParam2, bool bParam, float fParam1, float fParam2, MyClass& c1, MyClass2& c2);
    #define DoWorkLambda [](uint32_t dParam1, uint32_t dParam2, bool bParam, float fParam1, float fParam2, MyClass& c1, MyClass2& c2) -> bool
    void DoWork(DoWorkFunc func);

.cpp:
    bool MyClass::MyFunc(uint32_t val) {
        DoWork(DoWorkLambda { return c2.mVal < c1.mVal + fParam1 + fParam2; } );

        auto f1 = DoWorkLambda { return (bParam ? dParam1 : c1.mVal) < mVal; };
        auto f2 = DoWorkLambda { return ((dParam1 & dParam2) == 0) == bParam; };

        auto f = val < 3 ? f1: f2;
        DoWork(f);
    }

Это хорошо работает для одноразового решения, но заканчивается довольно грязным заголовком для нескольких объявлений функций

.h:

    typedef bool (*DoWorkFunc1)(uint32_t dParam1, uint32_t dParam2, bool bParam, float fParam1, float fParam2, MyClass& c1, MyClass2& c2);
    #define DoWorkLambda1 [](uint32_t dParam1, uint32_t dParam2, bool bParam, float fParam1, float fParam2, MyClass& c1, MyClass2& c2) -> bool
    void DoWork1(DoWorkFunc1 func);

    typedef bool (*DoWorkFunc2)(uint32_t dParam1, uint32_t dParam2, bool bParam, float fParam1, float fParam2, MyClass& c1, MyClass3& c2);
    #define DoWorkLambda2 [](uint32_t dParam1, uint32_t dParam2, bool bParam, float fParam1, float fParam2, MyClass& c1, MyClass3& c2) -> bool
    void DoWork2(DoWorkFunc2 func);

    ...

Дляссылка, вот как выглядит код без препроцессора:

.h:
    typedef bool (*DoWorkFunc)(uint32_t dParam1, uint32_t dParam2, bool bParam, float fParam1, float fParam2, MyClass& c1, MyClass2& c2);
    void DoWork(DoWorkFunc func);

.cpp:
    bool MyClass::MyFunc(uint32_t val) {
        DoWork([](uint32_t dParam1, uint32_t dParam2, bool bParam, float fParam1, float fParam2, MyClass& c1, MyClass2& c2) -> bool
            {
                return c2.mVal < c1.mVal + fParam1 + fParam2;
            }
        );

        auto f1 = [](uint32_t dParam1, uint32_t dParam2, bool bParam, float fParam1, float fParam2, MyClass& c1, MyClass2& c2) -> bool
        {
            return (bParam ? dParam1 : c1.mVal) < mVal;
        };
        auto f2 = [](uint32_t dParam1, uint32_t dParam2, bool bParam, float fParam1, float fParam2, MyClass& c1, MyClass2& c2) -> bool
        {
            return ((dParam1 & dParam2) == 0) == bParam;
        };

        auto f = val < 3 ? f1: f2;
        DoWork(f);
    }

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

.h:

struct DoWorkParams {
  uint32_t dParam1;
  uint32_t dParam2;
  bool bParam;
  float fParam1;
  float fParam2;
  MyClass& c1;
  MyClass2& c2;
};
typedef bool (*DoWorkFunc)(DoWorkParams);
void DoWork(DoWorkFunc func);

.cpp:

bool MyClass::MyFunc(uint32_t val) {
    DoWork([](auto p) { return p.c2.mVal < p.c1.mVal + p.fParam1 + p.fParam2; } );

    auto f1 = [](auto p) { return (p.bParam ? p.dParam1 : p.c1.mVal) < p.mVal; };
    auto f2 = [](auto p) { return ((p.dParam1 & p.dParam2) == 0) == p.bParam; };

    auto f = val < 3 ? f1: f2;
    DoWork(f);
}

in вам необходимо изменить auto p на DoWorkParams p,но функция lambdas auto была одной из первых функций , которые поддерживались компиляторами, так что, вероятно, она работает.

Если несколько различных функций совместно используют параметры, вы можете использовать наследование.

struct DoWorkBaseParams {
  uint32_t dParam1;
  uint32_t dParam2;
  bool bParam;
  float fParam1;
  float fParam2;
};
struct DoWorkParams1:DoWorkBaseParams {
  MyClass& c1;
  MyClass2& c2;
};
struct DoWorkParams2:DoWorkBaseParams {
  MyClass& c1;
  MyClass3& c3;
};

и т. Д.

0 голосов
/ 27 сентября 2018

Должна быть возможность назначить лямбда-функцию для эквивалентного необработанного указателя на функцию, но ТОЛЬКО если она НЕ использует аргументы области видимости - то есть квадратные скобки в лямбда-объявлении ДОЛЖНЫ быть пустыми.

Так что выдолжен быть в состоянии объявить тип функции.Использовать синтаксис проще всего:

using DoWorkFnType =bool (uint32_t , uint32_t , bool , float , float , MyClass& , MyClass2& );
void DoWork(DoWorkFnType* fn);

bool MyClass::MyFunc(uint32_t val) {
    DoWorkFnType* f1 = [](uint32_t dParam1, uint32_t dParam2, bool bParam, float fParam1, float fParam2, MyClass& c1, MyClass2& c2) -> bool
    {
        return (bParam ? dParam1 : c1.mVal) < mVal;
    };
    DoWorkFnType* f2 = [](uint32_t dParam1, uint32_t dParam2, bool bParam, float fParam1, float fParam2, MyClass& c1, MyClass2& c2) -> bool
    {
        return ((dParam1 & dParam2) == 0) == bParam;
    };

    auto f = val < 3 ? f1: f2;
    DoWork(f);
}

void DoWork(DoWorkFnType* fn)
{
  bool res= fn(arg1,arg2,arg3,arg4,arg5.arg6,arg7);
}

Если ваша лямбда использует локальную область видимости, то только std :: function будет работать для передачи лямбда-функции дочерней функции.

Это не ясно ввсе из вашего кода, что вы ожидаете от DoWork, или как он собирает 7 значений аргументов, необходимых для вызова f, поэтому мне нужно оставить его там.

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