我需要创建一个大致如下所示的类:
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
)。在基类的构造函数中,我需要知道父节点的实际类型,这就是我使用模板构造函数的原因。
我同意不允许节点的复制构造。事实上,节点的复制操作并没有明确的定义。但是,简单地将复制构造函数声明为已删除并不能满足我的要求。
最佳答案
Tag Dispatching 是一种习惯用法,用于为函数提供独特的签名,类似于您的“虚拟变量”想法。
struct UseSpecialConstructor{};
template <typename ...T>
explicit C(UseSpecialConstructor, const T&...) { /* implementation */ };
在内联时,编译器擅长优化这个未使用的空结构参数,并且调用代码从您的显式标记名称中获得可读性。
C c1;
C c2{ C::UseSpecialConsructor{}, c1 };
关于c++ - 复制构造函数和模板构造函数之间的冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48331774/