有没有办法在C++ 11中使用条件进行构造函数委派?

Can*_*Bal 2 c++ constructor delegation c++11

我试图使用C++ 11委托功能来构造一个以输入值为条件的类.这甚至可能吗?下面的代码在语法上不正确,但我把它放在这里是为了澄清.

enum MyEnum { A, B };

typedef struct {
  int val;
  MyEnum e;
} MyStruct;

class Foo {
public: 
  Foo(MyStruct a, MyStruct b) {} // a.e == A and b.e == B (assert checked)
  Foo(MyStruct x) {
    if (x.e == A) {
      return Foo(x, {0, B});
    } else {
      return Foo({0, A}, x);
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

Yak*_*ont 7

Foo(MyStruct x):
  Foo(
    (x.e==A)?x:MyStruct{0,B},
    (x.e==A)?MyStruct{0,A}:x
  )
Run Code Online (Sandbox Code Playgroud)

是一种直接的方式.请注意,委托给同一个ctor,但参数会发生变化.这与您的示例一致,但可能不是您真正的问题.


现在,假设你有一个更复杂的问题.您真的想要根据运行时值调用不同的构造函数吗?

如果我们想要根据运行时间值调用不同的ctor,我们可能不得不依赖(希望省略)复制或移动ctors.

简单的方法就是

Foo(MyStruct x):
  Foo( (x.e==A)?
    Foo{x, {0,B}}:
    Foo{{0,A}, x}
  )
{}
Run Code Online (Sandbox Code Playgroud)

我们调用Foo复制/移动ctor与不同的Foo取决于x.e.这有一个阻塞省略的小问题.

此时你应该停下来.因为下一步非常疯狂.


这是一种过于花哨的方式来避免构造候选者Foo,我认为甚至允许省略(没有线索,如果编译器实际上会这样做):

template<class T>
struct delayed_construct {
  void const* data;
  T(*func)(void const*);
  template<class F>
  delayed_construct( F const& f ):
    data(&f),
    func([](void const* ptr)->T{
      F const& f = *static_cast<F const*>(ptr);
      return f();
    })
  {}
  T operator()() const {
    return func(data);
  }
};
struct Foo {
  explicit Foo( delayed_construct<Foo> d ):Foo(d()) {}
  Foo(MyStruct a, MyStruct b) {}
  Foo(MyStruct x):
    Foo( (x.e==A)?
      delayed_construct<Foo>{[&]()->Foo{
        return {x, {0,B}};
      }}:
      delayed_construct<Foo>{[&]()->Foo{
        return {{0,A}, x};
      }}
    )
  {}
};
Run Code Online (Sandbox Code Playgroud)

它做了一堆非常复杂的东西,允许你在两个不同的ctors之间选择.如果不挑选那个电话,即使是ctors的论点也不会被评估.

delayed_construct<Foo>基本上是std::function<F()>假定它的生命周期是暂时的,并且通过这样做可能会受到编译器稍微更容易的优化.

我相信标准允许在Foo创建的lambdas中Foo(MyStruct x)构造直接构造Foo我们从中调用它.我可能错了,很可能即使我是对的,编译器也可能不会这样做.