繁体   English   中英

模板类中的通用模板指针

[英]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

最接近实现目标的方法是:

  1. Foo所有实例创建一个基类。
  2. 存储指向基类的指针。

演示概念的简单程序:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM