2017-12-19 10 views
1

同じクラスへのポインタを持つテンプレートクラスを持っていますが、必ずしも同じタイプを使用する必要はありません。ここに例があります:テンプレートクラスの汎用テンプレートポインタ

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内のポインタを定義することができますか?

+0

あなたが求めていることは私には分かりません。どんな種類の 'Foo'を指すポインタを要求していますか?もしそうなら、 'Foo 'を、テンプレート化されていない基底クラスから派生させることを検討してください。 –

+0

"同じクラス(ただし必ずしも同じ型ではない)" - いいえ、**クラス**は** one **型を定義します。 **同じテンプレートの異なるインスタンス化**を話しています。テンプレートとクラスを混乱させないでください。彼らは2つの異なったものです。クラステンプレートは、クラスを作成するための**パターン**です。それはクラスではありません。 –

+0

@FrançoisAndrieuxはい、それはまさに私が意味していたものです。あなたが提案した解決策は問題を解決しましたが、その場合、私はFooに属するものを使用できません。例えば ​​'eval'というテンプレート関数があるとします:' a-> eval() '' FooBaseにはevalという名前のメンバはありません。 – Elirovi

答えて

1

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); 
} 
+1

さて、わかりました。しかし、私はまだ解決策がありません。 – Elirovi

+1

@Elirovi、 'Foo 'に 'Foo 'へのポインタを格納する正当な理由は何ですか? –

+0

ここでのポイントは、OPが本当に 'Foo'の' a'データメンバで何をしたいのかということです。 –

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を打っていると思います。

0

共通の基底クラスとの溶液に加えて別の可能性は、void *代わりにFoo *としてFooaデータメンバのタイプを定義から成ります。その方法は、任意のデータポインタが(この1つは汎用ポインタだろう)、それに割り当てることができます

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>(); 
} 

ベア心​​の中で0の右のテンプレートのインスタンスを使用していません(たとえば、aを正しいタイプのポインタにキャストしない)は、未定義の動作になります。

関連する問題