【问题标题】:Delegate constructor and default argument depending on other arguments根据其他参数委托构造函数和默认参数
【发布时间】:2019-01-12 09:22:32
【问题描述】:

我有一个 B 的构造函数,带有一些默认参数,具体取决于其他参数:

struct A
{
    int f();
    A(const A&) = delete;
    A(A&& );
    // ....
};

struct B
{
    B(A a, int n=a.f()) {//...}
    // ...
};

这显然不能以这种方式工作,所以我想使用委托构造函数:

struct B
{
      B(A a, int n) {//...}
      B(A a): B(a, a.f()) {}
};

但是,这也不起作用,因为 A 的复制构造函数被删除了。所以我需要类似的东西

struct B
{
      B(A a, int n) {//...}
      B(A a): B(std::move(a), a.f()) {}
};

然而,据我所知,不能保证 a.f() 在 std::move 之前被评估,所以结果是未定义的。是否有可能在 std::move 之前获得 a.f() 的值,还是我应该更好地编写两个单独的构造函数?

【问题讨论】:

  • 为了简单的生活,你不能在Aprotected中创建复制构造函数吗?
  • 我可以。这只是一个简化版本,以显示问题的本质;实际情况其实更复杂。

标签: c++ constructor delegates


【解决方案1】:

你为什么不做一些更简单的事情 - 即重载你的构造函数?

struct B
{
    B(A a) {
        int n = a.f();
        ...
    }
    B(A a, int n) {
        ...
    }
};

如果您不喜欢在 ... 中重复您的代码,您总是可以只调用一个私有成员函数来完成其余的构造。

【讨论】:

  • 是的,这也是我目前使用的版本。它工作得很好,但我更喜欢委托构造函数,因为它使代码依赖关系更加清晰。 (这就是引入委托构造函数的原因)。
  • @HelmutZeisel 而且,您还需要特定的评估顺序。这种类型的推理是由 C++ 的命令式特性处理的,而不是函数式的。所以,我认为,在你的情况下,有一系列语句,而不是漂亮的函数调用是要走的路。
  • 是的。我将继续使用没有委托构造函数的解决方案。哪种解决方案更清晰主要是口味问题。此外,正如本示例还显示的那样,委托构造函数效率较低,因为它不允许复制省略(然而,这在特定情况下并不重要)。
【解决方案2】:

对此有更多可能的解决方案。

  1. 最简单的方法是让a成为一个指针:

    struct B
    {
         B(A* a, int n) {...}
         B(A* a): B(a, a->f()) {}
    };
    
  2. 更复杂的方法是尝试将a 设为引用:

    struct B
    {
          B(A& a, int n) {...}
          B(A& a): B(a, a.f()) {}
    };
    

我不会建议这种解决方案。指针是一种更简洁的方法。

编辑:

  1. 通过实用程序库中的 std::move

    struct B
    {
          A&& a:
          int n:
    
          B(A&& a, int n): a(std::move(a)), n(n) {...}
          B(A&& a): B(std::move(a), a.f()) {...}
    };
    

【讨论】:

  • 在引用或列表中,您只需再添加四个空格即可缩进代码。
  • 是的,那是工作,但语义有所不同。我希望 B 拥有 a 的所有权,但在您的情况下,调用者保留所有权。
  • 你正在寻找的东西是一个移动构造函数。如果我测试过,我会更新答案。
  • 我在其他两个中添加了一个 3. 选项,希望这对你有用。
  • @CygnusX1 没关系,因为张贴者仅使用参考。没有任何动作。
猜你喜欢
  • 1970-01-01
  • 2020-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-09
  • 1970-01-01
  • 2021-06-15
  • 2016-03-29
相关资源
最近更新 更多