在类体中拆分构造函数代码

时间:2018-02-25 16:32:06

标签: c++

在C ++中是否有可能以某种方式将构造函数拆分为类体中的多个部分?像Scala或Kotlin一样?我需要它用于使用C ++元编程编写的DSL。

我的数据成员具有非平凡的初始化序列,我想指定初始化代码和成员声明。

今天我有:

class foo {
    foo() {
       // code to initialize a;
       a.something();  
       a.other_thing()
       // code to initialize b;
       b.other_thing(a);             
    }

    T a;     
    T b; 
};

相反,我想将初始化代码与成员声明一起指定,例如:

class foo {
    T a; 
    {
       a.something();  
       a.other_thing()
    }  

    T b; 
    {
       b.other_thing(a);             
    } 
};

我找到了两个我不喜欢的解决方案。 首先是将std :: function参数传递给每个类型,因此我可以像这样初始化数据成员:

class foo {
    a{ [&](){
       // initialization code
    }};
};

不幸的是,这需要重构我使用的所有第三方库。

第二个选项是引入一个“虚拟”数据成员来执行lambda:

T a;
dummy_type a_init = [](&) { ... }

这可以隐藏在MACRO中:

T a; INIT(a) { ... }

一切都很好,但是如何在C ++中创建一个零大小的对象,这样每个虚拟初始化器都不会增加类的大小?

1 个答案:

答案 0 :(得分:3)

如果立即调用lambda,您可以使用lambda而不进行任何外部更改:

01 function negamax(node, depth, color)
02     if depth = 0 or node is a terminal node
03         return color * the heuristic value of node
04     bestValue := −∞
05     foreach child of node
06         v := −negamax(child, depth − 1, −color)
07         bestValue := max( bestValue, v )
08     return bestValue

漂亮吗?一定不行!但它应该有效,除非class foo { foo() : a([=]() { T a; a.something(); a.other_thing(); return a; }()) , b([=]() { T b; b.other_thing(a); return b; }()) {} T a; T b; }; 很难/不可能移动/复制。

live demo

您也可以内联移动初始化工具:

T

live demo

或者在某处设置工厂函数/类型,而只是调用它。

如果你真的很绝望,那就让成员class foo { T a = [=]() { T a; a.something(); a.other_thing(); return a; }(); T b = [=]() { T b; b.other_thing(a); return b; }(); }; 进行动态分配,就像过去那样(你可以随心所欲地在你的构造函数体内分散)。可能是最简单的解决方案。

unique_ptr

live demo