我需要创建一个大致应该如下的类:
class C {
public:
C() = delete;
C(const C&) = default;
C(C&&) = default;
template <typename ...T>
explicit C(const T&...) { /* implementation */ };
};
这个类有一个问题:当我想要复制构造的情况与我想用类型为C
的单个参数调用模板构造函数的情况无法区分。
问题:此案有任何常见做法或建议吗?
我正在考虑向模板构造函数添加一个虚拟变量,但是,我对此并不满意。
UPD 对我正在做的事情的一点解释:
我正在做一个非循环图形的结构。我的图书馆用户应按以下方式编写图表:
auto x = graph::NodeType1();
auto y = graph::NodeType2();
auto z = graph::NodeType3(x, y);
// ... etc.
所有节点类都派生自基类(在此问题中称为C
)。在基类的构造函数中,我需要知道父节点的实际类型,这就是我做模板构造函数的原因。
我禁止复制节点构建。实际上,对于节点的复制操作没有明确的定义。但是,简单地将复制构造函数声明为已删除并不能完成我想要的操作。
答案 0 :(得分:3)
标签调度是一种用于为函数提供独特签名的习惯用法,类似于“虚拟变量”的想法。
struct UseSpecialConstructor{};
template <typename ...T>
explicit C(UseSpecialConstructor, const T&...) { /* implementation */ };
内联时,编译器擅长优化这个未使用的空结构参数,并且调用代码可以从显式标记名称中获取可读性。
C c1;
C c2{ C::UseSpecialConsructor{}, c1 };