簡體   English   中英

使用函數指針前向聲明作為lamba聲明

[英]Using function pointer forward declaration as lamba declaration

我最接近這樣的東西嗎?

.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(DoWorkFunc { return c2.mVal < c1.mVal + fParam1 + fParam2; } );

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

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

這是我能夠獲得的最接近的干凈解決方案,它需要一個主要復制粘貼的lambda前向聲明解決方案。

.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);
    }

應該可以將lambda函數分配給等效的原始函數指針,但只有在不使用范圍參數的情況下,即lambda聲明中的方括號必須為空。

因此,您應該能夠聲明函數類型。 使用語法最簡單:

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);
}

如果您的lambda使用本地范圍,則只有std :: function可以將lambda傳遞給子函數。

從您的代碼中根本不清楚您希望DoWork做什么,或者它如何收集調用f所需的7個參數值,因此我將需要保留它。

。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);
}

您需要將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;
};

等等

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM