有一个模板是指来自共同继承的成员 class
Having a template refer to a member from a jointly-inherited class
很明显,下面的代码无法编译,因为它在 'n = n_init' 行给出了 "undeclared identifier" 错误。尽管如此,对于人类 reader 来说,意图可能已经足够清楚了:我想为 class 声明一个模板,它永远不会被自己实例化,而只能通过与另一个 class 一起的多重继承来实例化它保证至少包含一个 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);
这个,或者任何类似的事情,真的可以做到吗?
为了使其工作,模板 class 必须派生自包含 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;
很明显,下面的代码无法编译,因为它在 'n = n_init' 行给出了 "undeclared identifier" 错误。尽管如此,对于人类 reader 来说,意图可能已经足够清楚了:我想为 class 声明一个模板,它永远不会被自己实例化,而只能通过与另一个 class 一起的多重继承来实例化它保证至少包含一个 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);
这个,或者任何类似的事情,真的可以做到吗?
为了使其工作,模板 class 必须派生自包含 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;