【发布时间】:2014-03-12 18:26:28
【问题描述】:
简介: C++ 标准区分了依赖于模板参数的符号名称和不依赖模板参数的名称,这称为两阶段名称查找(参见here)。定义模板时会尽快解析非相关名称。另一方面,依赖名称仅在模板实例化时解析。
示例:
template<class T> struct Base {
typedef T type;
static const int n = 3;
virtual int f() = 0;
int f(int x) { return x * 2; }
};
// doesn't compile!
template<class T> struct Derived : Base<T> {
type field; // The compiler doesn't know Base<T>::type yet!
int f() { return n; } // the compiler doesn't know n yet, and f(int) is maksed!
};
目前,我所做的是这样定义Derived:
template<class T> struct Derived : Base<T> {
typedef Base<T> Parent;
typedef typename Parent::type type; // correct but
using Parent::n; // boring, long
using Parent::f; // and harder to maintain
type field;
int f() { return n; }
};
对我来说,面向对象编程的主要目标之一是减少代码重复;这种失败的目的……
问题:是否有另一种方法可以通过使用一些我不知道的语法或聪明的技巧来定义Derived?我喜欢这样的东西:
template<class T> struct Derived : Base<T> {
using Base<T>::*; // I promise I won't do strange specializations of Base<T>
type field;
int f() { return n; }
};
编辑澄清:也许我不够具体。假设您在Base 中有大约十个类型定义/字段/函数,以及数十个派生类,每个类的特定代码不到 5 行。这意味着大部分代码将包含重复的 typedef 和 using 子句,我知道没有办法完全避免这种情况,但我希望尽量减少这种重复代码。
感谢您提供任何使这更易于编写和维护的想法!
【问题讨论】:
-
字符串
typename Base<T>::type T field;是什么意思?应该是typename Base<T>::type field;或者T field;,我觉得…… -
@Constructor:谢谢,已修复!
-
这个问题有4种解决方案:1)使用前缀
Base<T>::n,2)使用前缀this->n,3) 添加语句using Base<T>::n, 4) 使用启用许可模式的全局编译器开关。这些解决方案的优缺点和细节在stackoverflow.com/questions/50321788/…
标签: c++ templates inheritance