我有一个模板类,它有一个指向同一个类的指针(但不一定使用相同的类型)。这是一个例子:
template<class T>
class Foo{
Foo(){}
Foo* a;
template<class U>
void bar(Foo<U>* b){a=b;}
}
当我在我的main函数中使用它时,一切似乎都在工作,直到我为参数使用不同的模板。
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
中定义一个具有&#34;泛型&#34;的指针。指向同一个类的指针?
答案 0 :(得分:1)
无论如何,我可以在类Foo中定义一个指针,它有一个&#34;泛型&#34;指向同一个类的指针?
你拥有的是正确的。你期望看到的可能是一个误解。
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);
}
答案 1 :(得分:0)
无论如何,我可以在类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 problem。
答案 2 :(得分:0)
除了具有公共基类的解决方案之外的另一种可能性包括将a
中Foo
数据成员的类型定义为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
转换回正确类型的指针)将导致未定义的行为。
答案 3 :(得分:0)
如何向模板添加额外的参数:
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>
可能有效。