【问题标题】:Can I make a table of String + lambdas that have the same signature?我可以制作一个具有相同签名的字符串 + lambda 表吗?
【发布时间】:2011-11-07 20:59:22
【问题描述】:

我有这个模式:

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

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

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

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

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

请随时要求我进一步澄清。因为我还没有机会真正使用它们,所以我在黑暗中摸索着 lambdas...

【问题讨论】:

  • 我可以想到一些明显的改进——比如将 if !x 条件放在 lambda 之外,因为这是一个不变量。但我需要知道追求这一点是否有意义。 :)
  • 我相信你在这里需要一个模板,因为你不能声明一个 lambdas 类型名称 IIRC

标签: c++ visual-studio-2010 lambda c++11


【解决方案1】:

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

struct Table {
    const char* label;
    void (*lambda)(const char*, Thing*);
};

如果任何 lambda 表达式是有状态的(即 [] 不为空),则不能使用函数指针。不过,您可以使用std::function:

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

Visual C++ 2010 不支持 lambda 到函数指针的转换(该转换是在 Visual C++ 2010 发布后添加到语言中的),但 Visual C++ 11 开发人员预览版确实支持这种转换。如果您使用的是 Visual C++ 2010,则可以使用std::function 解决方案。

【讨论】:

  • 编译器是否允许将 lambda 语法嵌入到表的静态初始化列表中,这将决定...
  • @Mordachai:我没有再安装 Visual C++ 2010,但是 Visual C++ 11 开发者预览版接受这两者,并在表的静态初始化程序中使用 lambda。
  • error C2440: 'initializing' : cannot convert from '`anonymous-namespace'::' to 'void (__cdecl *)(ITEM *,CDynamicMenuItem *)'
  • 正确:见答案的最后一段。 Visual C++ 2010 不支持 lambda 到函数指针的转换。不过,它确实支持std::function。
  • std::function 版本也不错,因为它不需要任何特定的可调用类型;你可以使用任何可调用的东西。通过获取函数指针,您可以将使用限制为仅可降解的 lambda 表达式或实际的函数指针。
猜你喜欢
  • 2013-07-31
  • 2011-10-12
  • 2020-02-12
  • 1970-01-01
  • 2016-04-04
  • 2020-03-17
  • 2017-02-14
  • 2019-12-31
  • 1970-01-01
相关资源
最近更新 更多