来自模板类的繁琐继承
Cumbersome inheritance from template class
本文关键字:继承 更新时间:2023-10-16
下面是一个具有某些功能的模板的代码。几个结构将从中继承,每个结构将使用不同的UniqueTag。也就是说,每个结构都继承自一个唯一的模板。对于天真的尝试#1,代码变得非常冗长。尝试#2在详细程度方面稍微好一点,但删除了能够通过模板实例化更改UniqueTag值的所需属性。3号的宏版本很难让它变得更好。
我当然不是c++语法大师,这让我想知道:这能表达得更清楚吗
尝试#1
template <int UniqueTag, typename Verbose, typename Arguments>
struct Base {
static const int tag = UniqueTag;
// Random example functionality
float data_;
Base(float data) : data_(data) {}
int do_stuff(Verbose& v, Arguments& a) {
return v + a;
}
};
template <int UniqueTag, typename Verbose, typename Arguments> // once...
struct Foo : Base<UniqueTag, Verbose, Arguments> { // twice...
typedef Base<UniqueTag, Verbose, Arguments> base_t; // thrice..!
Foo(float data) : base_t(data) {}
int do_it() {
Verbose v(10);
Arguments a(10);
return base_t::do_stuff(v, a); // must qualify dependent class name
}
};
尝试#2
一个稍微合理的方法是将模板参数存储在基类中。现在Foo
不必是一个模板类。它可以从模板继承并通过模板引用类型,而不存在依赖类问题然而,它确实带走了Foo2
的模板性,这是不可接受的
template <int UniqueTag, typename Verbose, typename Arguments>
struct Base2 {
typedef Verbose verbose_t;
typedef Arguments arguments_t;
static const int tag = UniqueTag;
float data_;
Base2(float data) : data_(data) {}
int do_stuff(Verbose& v, Arguments& a) {
return v + a;
}
};
typedef Base2<1, int, int> Foo2Base;
struct Foo2 : Foo2Base {
Foo2(float data) : Foo2Base(data) {}
int do_it() {
verbose_t v(10);
arguments_t a(10);
return do_stuff(v, a);
}
};
尝试#3
上一个例子的宏版本也是可能的,但它只保存了一行,同时使代码不那么明显。
#define BASE_MACRO(name, tag, typeA, typeB)
typedef Base2<tag, typeA, typeB> name ## Base;
struct name : name ## Base
BASE_MACRO(Foo3, 2, int, int) {
Foo3(float data) : Foo3Base(data) {}
int do_it() {
verbose_t v(10);
arguments_t a(10);
return do_stuff(v, a);
}
};
// To compile all of the above.
#include <iostream>
int main() {
Foo<0, int, int> a(1.0);
std::cout << a.do_it() << std::endl;
Foo2 b(1.0);
std::cout << b.do_it() << std::endl;
Foo3 c(1.0);
std::cout << c.do_it() << std::endl;
};
如果是这样的话,即使是明确的"没有更好的方式来表达这一点"也会有所帮助。
怎么样?
使do_stuff成为模板方法
template <int UniqueTag>
struct Base {
static const int tag = UniqueTag;
// Random example functionality
float data_;
Base(float data) : data_(data) {}
template <typename Verbose, typename Arguments>
int do_stuff(Verbose& v, Arguments& a) {
return v + a;
}
};
template <int UniqueTag, typename Verbose, typename Arguments> // once...
struct Foo : Base<UniqueTag> { // shorter reference
typedef Base<UniqueTag> base_t; // shorter reference
Foo(float data) : base_t(data) {}
int do_it() {
Verbose v(10);
Arguments a(10);
return base_t::do_stuff(v, a); // must qualify dependent class name
}
};
保持Foo的模板性,同时减少的冗长性
经过一番周旋,我想出了自己的简化方法。只需将整个基作为单个模板参数传递即可。
template <int UniqueTag, typename Verbose, typename Arguments>
struct Base {
typedef Verbose verbose_t;
typedef Arguments arguments_t;
static const int tag = UniqueTag;
float data_;
Base2(float data) : data_(data) {}
int do_stuff(Verbose& v, Arguments& a) {
return v + a;
}
};
template <typename Base>
struct Foo : Base {
Foo(float data) : Base(data) {}
int do_it() {
typename Base::verbose_t v(10);
typename Base::arguments_t a(10);
return this->do_stuff(v, a);
}
};
Foo<Base<5, int, int> > f(1.0);
可选地,结合@jsantander的回答,它在各种情况下都会有所帮助。
相关文章:
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 头文件-继承c++
- 为什么在保护模式下继承升级不起作用
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 混合组合和继承的C++问题
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- 公共与私人继承
- 如何创建从同一类继承的不同对象的向量
- 如何从另一个文件继承私有成员变量和公共函数
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 带有继承的C++工厂
- 我应该避免多重实现继承吗
- C++继承更改成员
- 从具有默认值的部分指定模板类继承时发生SWIG错误,具有不带默认值的正向声明
- 关于C++中具有多重继承"this"指针的说明
- 尝试使用继承和模板实现CRTP.Visual Studio正在生成编译器错误
- 如何在QT Creator上将QWidget声明为继承类的对象