Lambda作为班级成员

时间:2020-03-04 17:23:00

标签: c++ c++17

我目前正在建立一个处理数字数据的框架。我从类Collection开始,它具有所谓的属性,它们只是用于包含源数据的std :: vectors(实际上是std :: variant,因为它们的数据可能是整数或浮动)。在这种情况下,代表碰撞事件中产生的一组电子的典型集合看起来像这样:

  Collection<int, float> electron("electron", ...);
  electron.add_attribute("px", ...);
  electron.add_attribute("py", ...);
  electron.add_attribute("pz", ...);
  electron.add_attribute("charge", ...);

其中...只是与数据源相关的std :: string参数,它们存储在类中。定义了所有Collection之后,实际的读取结果就会在代码的稍后部分发生。还有其他与过滤,排序等有关的方法。

现在我要定义另一个类,我们称它们为Aggregate,它应该包含来自多个Collections的转换数据(但工作原理类似)。为此,我计划让Aggregate保存对相关Collections的引用,然后让Aggregate的add_attribute方法对相关转换采用lambda。这就是我被困住的地方。

具体来说,我该如何存储lambda?对于Collection,我将与源相关的字符串存储到成员std :: vector中,但显然这不适用于lambda。我已经考虑过std :: function,但是问题在于lambda不会具有相同的签名,因为如果我们考虑说两个电子集合的双电子聚集体,则双电子的电荷属性仅为charge1 + charge2,而mass属性要复杂得多。这就是我想象的在用户端的样子:

  auto sum_of_two = [] (auto p1, auto p2) { return p1 + p2; };
  auto energy_of_two = [] (auto px1, auto py1, auto pz1, 
                           auto px2, auto py2, auto pz2) { 
                    auto ee1 = (px1 * px1) + (py1 * py1) + (pz1 * pz1); 
                    auto ee2 = (px2 * px2) + (py2 * py2) + (pz2 * pz2); 
                    return std::sqrt(ee1) + std::sqrt(ee2); }

  Aggregate<int, float> dielectron("dielectron", electron, electron);
  dielectron.add_attribute("px", sum_of_two, "electron::px", "electron::px");
  dielectron.add_attribute("py", sum_of_two, "electron::py", "electron::py");
  dielectron.add_attribute("pz", sum_of_two, "electron::pz", "electron::pz");
  dielectron.add_attribute("charge", sum_of_two, "electron::charge", "electron::charge");
  dielectron.add_attribute("energy", energy_of_two, "electron::px", "electron::py", "electron::pz", "electron::px", "electron::py", "electron::pz");

当然,问题出在开发人员端。 add_attribute的签名可以用杂色书写,但其主体使我陷于困境。在尝试保存lambda时,我尝试将其包装在从空基继承的结构中,但是我一直无法存储或使用它们(或者只是拒绝编译)。我已经考虑过使用std :: tuples,但是我发现这种方法存在一些问题:

1-在这种情况下,我不知道如何编写类模板(可能很简单)

2-它迫使lambda类型成为Aggregate类模板的一部分,这使得类型重叠的检查更加困难,我这样做是为了确保贡献的Collection彼此一致

3-由于上述原因,元组及其属性可能必须与Aggregate实例一起初始化,这对我来说似乎没有吸引力(例如,没有add_attribute())

我只是没有达到正确的语法,还是在C ++ 17中这真的不可能吗?顺便说一句,我专注于lambda只是因为这是最初的想法,如果有其他方法可以做到这一点,我很高兴认识他们。

0 个答案:

没有答案