具有模板引用联合继承类中的成员
Having a template refer to a member from a jointly-inherited class
很明显,以下代码无法编译,因为它在"n = n_init"行处给出了"未声明的标识符"错误。尽管如此,对于人类读者来说,意图可能已经足够清楚了:我想为一个类声明一个模板,该类永远不会由自身实例化,而只能通过与另一个类一起进行多重继承,该类保证至少包含一个 int 类型的成员 'n' 和一个类型 T* 的成员 'p',但它(作为从其他地方获得的 C 结构)我不能自由地从另一个包含这些的模板派生领域:
// In a C header file from elsewhere:
// ----------------------------------
typedef struct {
float *p;
int n;
} float_array_C;
// In my C++ header file:
// ----------------------
template<typename T> class MyArray
{
public:
MyArray(int n_init)
{
n = n_init;
contents.resize(n);
p = contents.data();
}
virtual void mustExist() = 0;
private:
std::vector<T> contents;
};
class float_array : public float_array_C, public MyArray<float>
{
public:
float_array(int n) : float_array_C(), MyArray(n)
{}
virtual void mustExist() {}
};
...
float_array testArray(10);
我也尝试过这种方法,但收效甚微:
typedef struct {
float *p;
int n;
} float_array_C;
template<typename T1, typename T2> class MyArray
{
public:
MyArray(int n_init)
{
&T2::n = n_init;
contents.resize(n);
&T2::p = contents.data();
}
private:
std::vector<T1> contents;
};
typedef MyArray<float, float_array_C> floatArray;
...
float_array testArray(10);
这,或者任何与之类似的事情,实际上可以做到吗?
为了使它起作用,模板类必须派生自包含 n
的类型,然后您可以将其作为T::n
访问,其中 T
是模板参数。
(不能仅使用 n
访问继承的成员,因为它不是依赖名称,因此编译器将在编译模板本身时尝试解析它,而不是稍后在实例化模板时解析它,并且MyArray
或全局范围内不存在任何n
。 使用 T::n
会导致它成为依赖名称(具体取决于T
),因此名称的解析将延迟到模板实例化。
typedef struct {
float *p;
int n;
} float_array_C;
template <typename T>
class MyArray : public T
{
public:
MyArray(int n_init) {
T::n = n_init;
}
};
请注意,您将遇到如下代码问题:
class Foo : public float_array_C, public MyArray<float_array_C> { /* ... */ };
在这种情况下,Foo
和 MyArray<float_array_C>
都包含单独的 float_array_C
实例。 如果存在此问题,您可以使用虚拟继承进行float_array_C
:
template <typename T>
class MyArray : virtual public T { /* ... */ };
class Foo :
virtual public float_array_C,
public MyArray<float_array_C>
{ /* ... */ };
另一种只需要一个模板参数的方法:
typedef struct {
float *p;
int n;
} float_array_C;
template<typename T> class MyArray : public T
{
public:
MyArray(int n_init)
{
T::n = n_init;
contents.resize(T::n);
T::p = contents.data();
}
private:
std::vector<std::remove_pointer_t<decltype(T::p)>> contents;
};
typedef MyArray<float_array_C> floatArray;
相关文章:
- 为什么我可以通过SubBase类的公共继承方法打印出基类的私人继承成员
- 派生类调用使用非继承成员的继承函数
- 如果存在具有不同参数的继承成员,为什么对 C++ 结构函数的调用不明确?
- C :原始成员与继承成员的优先级
- 更改继承成员的地址
- C 是否可以不继承成员
- 使用模板的继承阴影继承成员
- 继承成员功能的模板专业化
- 不允许继承成员,为什么
- 派生模板类和继承成员变量的语法谜题
- 继承成员地址的C++标准
- 多级继承成员访问
- 访问专用模板的私有/继承成员变量
- 基模板继承成员,减少所需的类型
- 继承成员函数指针
- 模板专用化类不继承成员
- C++14正在初始化类构造函数初始化列表中的继承成员
- 具有专门初始化的继承成员变量
- 模板继承成员字段
- 访问数据成员的继承成员函数