[英]Generic template pointer in template class
我有一个模板类,它有一个指向同一个类的指针(但不一定使用相同的类型)。 下面是一个例子:
template<class T>
class Foo{
Foo(){}
Foo* a;
template<class U>
void bar(Foo<U>* b){a=b;}
}
当我在主函数中使用它时,一切似乎都在工作,直到我为参数使用不同的模板。
int main(){
Foo<double> f1;
Foo<double> f2;
f1.bar(&f1);// no Errors
Foo<bool> f3;
Foo<double> f4;
f3.bar(&f4);//Error : cannot convert 'Foo<double>*' to 'Foo<bool>*'
}
无论如何我可以在类Foo
中定义一个指针,该指针具有指向同一类的“通用”指针?
无论如何我可以在类 Foo 中定义一个指针,该指针具有指向同一类的“通用”指针?
你所拥有的是正确的。 您期望看到的内容可能是建立在误解之上的。
Foo<bool>
和Foo<double>
是完全不同的类。 类型/类模板允许您使用编译器生成新类型,但它们本身不是类。
如果您必须手动生成类,您将拥有:
class Foo_bool{
Foo_bool(){}
Foo_bool* a;
...
};
class Foo_double{
Foo_double(){}
Foo_double* a;
...
};
有了这个,很容易理解为什么你不能使用:
Foo_bool a;
Foo_double b;
a.a = &b; // Not allowed
这与使用没有什么不同:
Foo<bool> a;
Foo<double> b;
a.a = &b; // Not allowed
最接近实现目标的方法是:
Foo
所有实例创建一个基类。演示概念的简单程序:
class FooBase
{
public:
virtual ~FooBase() {}
};
template<class T>
class Foo : public FooBase {
public:
Foo(){}
template<class U>
void bar(Foo<U>* b){a=b;}
private:
FooBase* a; // Note the change. This is not Foo* any longer.
};
int main()
{
Foo<bool> a;
Foo<double> b;
a.bar(&b);
}
无论如何我可以在类 Foo 中定义一个指针,该指针具有指向同一类的“通用”指针?
这就是你已经拥有的:
Foo* a;
我认为,您真正想要的是指向Foo
任何实例化的指针。 那是不可能的。 问题是:你为什么想要那个? 如果您准确说出您要实现的目标,也许您可以获得更有用的答案。
一种可能性可能是使用基类:
class Base {
// whatever common functionality you want in Foo goes here
};
template<class T>
class Foo : public Base {
Foo(){}
Base* a;
template<class U>
void bar(Foo<U>* b){a=b;}
}
在您提供有关您要实现的目标的更多信息之前,很难说这是否适合您。 我认为我们在这里遇到了XY 问题。
除了具有公共基类的解决方案之外,另一种可能性包括将Foo
中的a
数据成员的类型定义为void *
而不是Foo *
。 这样任何数据指针都可以分配给它(这将是一个通用指针):
template<class T>
class Foo {
public:
Foo(){}
void* a;
template<class U>
void bar(Foo<U>* b){a=b;}
...
};
然后,您可以定义以下成员模板convert_ptr()
将指针转换回其原始类型:
template<class T>
class Foo {
...
template<class U>
Foo<U>* convert_ptr() {
return reinterpret_cast<Foo<U>*>(a);
}
};
举个例子:
int main(){
Foo<bool> f1;
Foo<double> f2;
f2.bar(&f1);
Foo<bool> *p = f2.convert_ptr<bool>();
}
请记住,并非使用权模板实例convert_ptr()
如:没有铸造a
回正确类型的指针)会导致不确定的行为。
如何向模板添加额外的参数:
template<class T, class U=T>
class Foo {
public:
Foo() {}
Foo<U>* a;
void bar(Foo<U>* b) { a = b; }
};
int main(){
Foo<bool, double> f3;
Foo<double> f4;
f3.bar(&f4);
return 0;
}
如果未指定第二个模板参数,它将等于第一个。 这意味着您的指针“a”将指向与“this”类型相同的对象。 如果指定了第二个参数并且它与第一个参数不同,则您的指针“a”将指向不同的类型。
这不是通用的解决方案,因为一旦创建了对象,就不能更改第二种类型。 但如果你从一开始就知道
Foo<bool>
需要指向
Foo<double>
它可能会起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.