[英]lambda expression to assign a member function pointer
我需要一個 lambda 表達式的語法,它將返回一個指向成員函數的指針。
例如我有A類:
class A
{
int x;
void (A::*SomeFunction)();
}
我想將 SomeFunction 設置為 lambda。 我試着這樣做:
A a();
a.SomeFunction = [this](){ printf("Hello from lambada %d",this->x);};
問題在於:
[this](){ printf("Hello from lambda %d",this->x);};
沒有給我一個指向 A 類成員函數的指針。它給了我一個指向普通函數的指針。 我如何在 lambda 中聲明這是 A 的成員函數。
或者,如果這樣的事情在 cpp 中是不可能的。 您如何建議我從 SomeFunction 指向的函數訪問 A 類的變量 x 而不使用虛函數(這種代碼每秒將運行大約 700 次)。
編輯:
明確地說,我確實關心性能。 但我需要這個的主要原因是特定的設計問題而不是性能。 我知道這在 cpp 中可能是不可能的。 歡迎提出解決方法的建議。
出於多種原因,這是不可能的。
首先,指向成員函數的指針與指向獨立函數的指針在類型上不同,非捕獲性 lambda 只能轉換為指向獨立函數的指針。
其次,您的 lambda 正在捕獲,因此,它根本無法轉換為指向函數的指針,並且只能保留為未指定類型的函子。
但是,您不應該考慮太多,只需將 lambda 存儲在std::function
。 誠然,您將以虛擬分派和與之相關的一些性能下降結束,但每秒 700 次算不了什么,而且您永遠不會因為虛擬分派而檢測到命中。
在定義之后,不可能向類添加額外的方法。 因此,由於在你的類中沒有方法A
,它不可能永遠集A::SomeFunction
以點的任何非靜態方法A
。 作為一種解決方法,你可以
void (*SomeFunction)(A*);
和
A a {}; // note {} instead of ()
a.SomeFunction = [](A* a){ /* do something with a->x */ };
來自評論:
這是 ECS 實施的一部分。 我只是不願意為 etch 系統創建一個新類,我想讓用戶選擇在場景構造函數中聲明系統或從系統類繼承。
你想要同一個類的不同行為而沒有任何間接性? 你必須放棄一個。
但是您也不必為每個系統編寫一個類。 您可以將該類設為模板,以便編譯器可以為每個系統生成一個類:
template<typename T>
struct A : private T {
A(T function) noexcept : T{std::move(function)} {}
void SomeFunction() {
(*this)(this);
}
int x = 0;
};
然后可以像這樣使用它:
auto lambda = [](auto a){ printf("Hello from lambda %d",a->x); };
auto my_a = A{lambda}; // Generate a new A type from lambda
my_a.SomeFunction(); // calls the lambda!
很好地跟進未來的人,這里有一個解決方法,可以讓它看起來更好。
我創建了一個模板類
template <class Parent,class Return, class...Params>
struct MemberLambda
{
Parent* self; // pointer to self
void (*lambda)(Parent * self,Params...);//the lambda
MemberLambda() = default;//Constructor
MemberLambda(Parent* self, void(*lambda)(Parent* self,Params...)) :
self(self),lambda(lambda) {};//Constructor
Return operator()(Params... p) const { return lambda(self,p...); };
void operator=(void (*lambda)(Parent* self, Params...)) {
this->lambda = lambda;
}
};
課堂使用:
class A {
public:
int someMember;
MemberLambda<A, void, int, int> func =
MemberLambda<A, void, int, int>(this, nullptr);
};
*注意在示例中我將 lambda 設置為nullptr
但它可以設置為 lambda 表達式。
在示例中, lambda 是A
的成員,采用兩個int
並返回void
。
用戶使用:
A a;
a.someMember = 3;
a.func = [](A* self, int a, int b){ std::cout << self->someMember + a + b; };
a.func(5,6);
將輸出 14,即 3 + 5 + 6。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.