如何编写工厂函数来初始化 C++ 中的 constexpr 引用?
Posted
技术标签:
【中文标题】如何编写工厂函数来初始化 C++ 中的 constexpr 引用?【英文标题】:How to write a factory function to initialize a constexpr reference in C++? 【发布时间】:2018-02-10 12:03:57 【问题描述】:我想通过一个工厂函数初始化一个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;
好的,我可以直接调用所有的构造函数,但我更喜欢工厂,因为
-
我不需要一遍又一遍地重复类型参数
工厂还可以根据参数列表(重载)甚至参数的 constexpr 属性选择适当的工作类。
问题可能与静态引用所需的静态存储有关。
是否不可能为此编写工厂?
如果是,为什么? 如果不是,如何正确实施?预期的用例是大型解析器调度表,当然还有更复杂的类。 语言标准是 C++11。不过,最好知道 C++17 是否有帮助,尽管它尚未得到广泛支持。
【问题讨论】:
@Jorge Y. 您的解决方案非常接近:从工厂中删除const
就可以了。您应该取消删除并更新它。可能是const
prevents RVO。
【参考方案1】:
只需在R
中使用右值引用并让您的工厂返回Worker<T>
,以便它可以绑定到右值引用
#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;
【讨论】:
r 值参考似乎不是故事的重要部分。工厂的返回类型必须是按值,并且必须是non-const。以上是关于如何编写工厂函数来初始化 C++ 中的 constexpr 引用?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C++ 子类的构造函数中初始化超类的 const 成员变量?