我有几个共享共同点的类:它们的构造方式和它们所拥有的数据。但是,每个人都有一个独特的dtor。因此,尝试删除代码重复并使它们从基类继承似乎是显而易见的。所以我从这开始:
class base{
protected:
int data;
public:
base() = default;
base(const base &) = delete;
base& operator=(const base &) = delete;
base(base &&) = default;
base& operator=(base &&) = default;
};
class derived: public base{
public:
~derived() {}
};
然而,出现了问题。我不能这样做
derived d;
derived e(std::move(d));
原因是因为derived
声明了一个dtor,这意味着不会生成移动ctor / assignment。所以我的下一个想法是颠倒继承,我想出了这个。因为我(在我的原始例子中)有多个派生和单个基础,我想这样做的方式是有多个基础和一个派生,这将被模板化指向不同的基础。
class base1{
public:
~base1() {}
};
class base2{
public:
~base2() {}
};
template<class T>
class derived: public T{
protected:
int data;
public:
derived() = default;
derived(const derived &) = delete;
derived& operator=(const derived &) = delete;
derived(derived &&) = default;
derived& operator=(derived &&) = default;
};
using derived1 = derived<base1>;
using derived2 = derived<base2>;
这一切都很好,花花公子,它编译!
但是,base1
和base2
需要访问data
中的元素base
,因此我认为将基数设为模板类,以便其函数可以访问{{1 }}。此外,基本实际上有时是模板化的,所以我也需要添加这个功能。到目前为止我所拥有的是:
data
但是,我确信有很多错误。我现在在GCC 4.9中得到的编译器错误是(当只使用template<class T1, class T2>
class base1{
public:
~base1() {
std::cout<<T1::data;
}
};
template<class T>
class base2{
public:
~base2() {
std::cout<<T::data;
}
};
template<template <class, class...> class T, class... Ts>
class derived: public T<typename derived, Ts...>{
protected:
int data;
public:
derived() = default;
derived(const derived &) = delete;
derived& operator=(const derived &) = delete;
derived(derived &&) = default;
derived& operator=(derived &&) = default;
};
using derived1int = derived<base1<int>>;
using derived1float = derived<base1<float>>;
using derived2 = derived<base2>;
时)模板参数1在派生类中无效。
答案 0 :(得分:0)
虽然评论中有有效的参数,但我设法创建了模板。在这里,万一其他人需要解决模板部分:
template<class T1, class Data>
class base1{
public:
~base1() {
std::cout<<static_cast<T1*>(this)->data << " " <<typeid(std::declval<Data>()).name();
}
};
template<class T>
class base2{
public:
~base2() {
std::cout<< static_cast<T*>(this)->data;
}
};
template<template <class, class...> class T, class ... Ts >
class derived: public T< derived<T, Ts...>, Ts...>{
friend class T<derived<T, Ts...>, Ts...>;
int data = 0;
public:
derived() = default;
derived(const derived &) = delete;
derived& operator=(const derived &) = delete;
derived(derived && d){
std::swap(data, d.data);
}
derived& operator=(derived && d){
std::swap(data, d.data);
return *this;
}
};
using derived1int = derived<base1, int>;
using derived1float = derived<base1, float>;
using derived2 = derived<base2>;