有没有办法使用C ++ 11中的条件构造函数委托? [英] Is there a way to do constructor delegation using a conditional in C++11?

查看:151
本文介绍了有没有办法使用C ++ 11中的条件构造函数委托?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用C ++ 11委托功能来构造一个基于输入值的类。这是可能吗?

I am trying to use C++11 delegation feature to construct a class conditioned on an input value. Is that even possible? The code below isn't syntactically correct but I'm putting it here for clarification purposes.

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


推荐答案

Foo(MyStruct x):
  Foo(
    (x.e==A)?x:MyStruct{0,B},
    (x.e==A)?MyStruct{0,A}:x
  )

是一种直接的方法。注意,同一个ctor被委托给,但是参数改变。这与你的例子是一致的,但也许不是你真正的问题。

is a direct way to do it. Note that the same ctor is delegated to, but the arguments change. This is consistent with your example, but maybe not your real problem.

现在,假设你有一个更复杂的问题。你实际上想要根据运行时间值调用不同的构造函数?

Now, suppose you have a more complex problem. You actually want a different constructor to be called based off the run time value?

如果我们想要基于运行时间值调用不同的ctor,

If we want a different ctor to be called based on a run time value, we may have to rely on (hopefully elided) copy or move ctors.

简单的方法只是

Foo(MyStruct x):
  Foo( (x.e==A)?
    Foo{x, {0,B}}:
    Foo{{0,A}, x}
  )
{}

取决于 xe ,使用不同的 Foo 复制/移动ctor 这有一个小问题阻塞elision。

where we invoke the Foo copy/move ctor with a different Foo depending on x.e. This has the minor problem of blocking elision.

此时你应该停止。因为下一步很简单。

At this point you should stop. Because the next step is pretty nuts.

这是一个过于漂亮的方式,避免构建候选人 Foo ,我认为甚至允许elision(没有线索,如果编译器实际上这样做):

Here is an overly fancy way to avoid constructing the candidate Foos, and I think even permits elision (no clue if a compiler would actually do it):

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

这是一堆非常复杂的东西,允许你在调用两个不同的ctors之间选择。

which does a pile of really complex stuff to allow you to pick between calling two different ctors. Even the arguments of the ctors are not evaluated if you don't pick that ctor to call.

delayed_construct< Foo> 基本上是一个 std :: function< F()> ,它假定它的生命周期将是一个临时的,编译器。

delayed_construct<Foo> is basically a std::function<F()> that presumes its lifetime will be a temporary, and by doing so may be subject to slightly easier optimization by the compiler.

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

I believe that the standard allows the Foo constructed in the lambdas created in Foo(MyStruct x) to directly construct the Foo we are calling it from. I may be wrong, and it is quite possible that even if I'm right, a compiler might not do it.

这篇关于有没有办法使用C ++ 11中的条件构造函数委托?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆