我可以创建一个具有相同签名的String + lambdas表吗?

Mor*_*hai 2 c++ lambda visual-studio-2010 c++11

我有这种模式:

Thing * y = FindNearestItem();
if (y && (MenuElement * x = FindMenuElementNamed("Identity")))
  x->SetText(FString("%.1f", y));
else if (x)
  x->Clear();
if (y && (MenuElement * x = FindMenuElementNamed("X1")))
  x->SetLocalData(y);
else if (x)
  x->Clear();
Run Code Online (Sandbox Code Playgroud)

基本上,我想使用一个静态表:[警告:非常草率的概念代码,无效,我是菜鸟,你已被警告]:

struct Table {
  const char * label;
  ?lambda? lambda;
} MyTable[] = {
  "Identity", [] (const char * label, Thing * y) { MenuElement * x = FindMenuElementNamed(label); (y && x) ? x->SetText(FString("%.1f", y)) : x->Clear(); },
  "X1", [] (const char * label, Thing * y) { MenuElement * x = FindMenuElementNamed(label); (y && x) ? x->SetLocalData(y) : x->Clear(); },
};

Thing * y = FindNearestItem();
for (int i = 0; i != countof(MyTable); ++i)
  MyTable[i].lambda(MyTable[i].label, y);
Run Code Online (Sandbox Code Playgroud)

请记住,每个标签的动作都不同 - 我表中的每一行.

因此模式大致相同,但方差在所采取的行动中,尽管它在每种情况下使用相同的数据集(x,y,标签).但我不能简单地调用x-> DoAppropriateThingFor(label,y); 我只是回过头来创建一个基于标签的长if/else级联...

请随时向我询问进一步的说明.因为我还没有机会真正使用它们,所以我在黑暗中与lambdas混在一起......

Jam*_*lis 5

只要所有lambda都是无捕获的(即,[]为空),就可以使用函数指针:

struct Table {
    const char* label;
    void (*lambda)(const char*, Thing*);
};
Run Code Online (Sandbox Code Playgroud)

如果任何lambda是有状态的(即,[]它不是空的),那么你不能使用函数指针.但是你可以使用std::function:

struct Table {
    const char* label;
    std::function<void(const char*, Thing*)> lambda;
};
Run Code Online (Sandbox Code Playgroud)

Visual C++ 2010不支持lambda-to-function-pointer转换(在Visual C++ 2010发布后,该转换已添加到该语言中),但Visual C++ 11 Developer Preview确实支持转换.如果您使用的是Visual C++ 2010,则可以使用该std::function解决方案.

  • `std :: function`版本也很好,因为它不需要任何特定的可调用类型; 你可以使用任何可赎回的东西.通过获取函数指针,您只能将使用限制为可降级的lambdas或实际的函数指针. (3认同)
  • 右:见答案的最后一段.Visual C++ 2010**不支持**lambda-to-function-pointer转换.但它**支持`std :: function`. (2认同)