c++ - 如何编写工厂函数来初始化 C++ 中的 constexpr 引用?

标签 c++ c++11 constexpr

我想通过工厂函数初始化一个 constexpr 引用,但未能成功。

#include <stdio.h>
using namespace std;

struct IWorker // common interface of workers
{ virtual void foo() const = 0;
};

template <typename T> // example worker
struct Worker : IWorker
{ T& Target;
  const T Source;
  constexpr Worker(T& target, const T& source) : Target(target), Source(source) {}
  virtual void foo() const { puts("Worker::foo"); Target = Source; }
};

template <typename T> // factory for Worker (and maybe others)
constexpr const Worker<T>& factory(T& target, const T& source)
{ return Worker<T>(target, source);
}

struct R // allow array of references
{ const IWorker& ref;
};

int iVal = 0;

constexpr R table[] 
{ { Worker<int>(iVal, 7) } // works
//, { factory(iVal, 8) } // does not work
};

int main()
{ printf("iVal = %i\n", iVal); // iVal = 0
  table[0].ref.foo();
  printf("iVal = %i\n", iVal); // iVal = 7
  return 0;
}

好的,我可以直接调用所有构造函数,但我更喜欢工厂,因为

  1. 我不需要一遍又一遍地重复类型参数
  2. 工厂还可以根据参数列表(重载)甚至参数的 constexpr 属性选择合适的工作类。

这个问题可能与静态引用所需的静态存储有某种关系。

不可能为此目的编写一个工厂吗?

  • 如果是,为什么?
  • 如果不是,如何正确实现?

预期用例是大型解析器分派(dispatch)表,当然还有更复杂的类。 语言标准是C++11。不过,尽管尚未得到广泛支持,但最好知道 C++17 是否有帮助。

最佳答案

只需在 R 中使用右值引用并让您的工厂退回 Worker<T>所以它可以绑定(bind)到右值引用

#include <stdio.h>
using namespace std;

struct IWorker // common interface of workers
{
  virtual void foo() const = 0;
};

template <typename T> // example worker
struct Worker : IWorker {
  T &Target;
  const T Source;
  constexpr Worker(T &target, const T &source)
      : Target(target), Source(source) {}
  virtual void foo() const {
    puts("Worker::foo");
    Target = Source;
  }
};

template <typename T> // factory for Worker (and maybe others)
constexpr Worker<T> factory(T &target, const T &source) {
  return Worker<T>(target, source);
}

struct R // allow array of references
{
  IWorker &&ref;
};

int iVal = 0;

constexpr R table[]{
    {Worker<int>(iVal, 7)} // works
    , { factory(iVal, 8) } // does not work
};

int main() {
  printf("iVal = %i\n", iVal); // iVal = 0
  table[0].ref.foo();
  printf("iVal = %i\n", iVal); // iVal = 7
  table[1].ref.foo();
  printf("iVal = %i\n", iVal); // iVal = 8
  return 0;
}

关于c++ - 如何编写工厂函数来初始化 C++ 中的 constexpr 引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48720545/

相关文章:

c++ - 在 Qt 中使用 QGraphicsScene 函数时出错

c++ - 如何正确检查 C++11 中的 std::function 是否为空?

c++ - 初始化列表中的类 constexpr 表达式

c++ - 分布在 -DBL_MAX 和 DBL_MAX 之间的随机 double

c++ - 为什么 constexpr 属性在应用于静态方法时不起作用?

c++ - 类内的静态 constexpr 初始化链

c++ - 错误 : No matching constructor for initialization of 'Matrix_ref<...>'

c++ - 你可以在 QDialog 中添加一个工具栏吗?

c++ - Noexcept 对派生类构造函数的 promise : can that be used without promising noexcept on base constructor?

c++ - 如何使用 C++ 中的模板从 json 中填充尽可能通用的 std::vector (11)?