0

テンプレート化されたクラス Foo があります。

template <class A, class B>
class Foo
{
public:
    Foo(A &aInstance);

private:
    Attr<Foo> _attr;
};

次に、Foo クラスの属性であり、テンプレート パラメーターとして Foo クラス自体を取る Attr という別のテンプレート クラスがあります。

template <class C>
class Attr
{
    class SomeType
    {
        SomeType();
        ~SomeType();
    };

    Attr(const SomeType* st);
    ~Attr();

private:
    Attr();
}

テンプレートの最初のパラメーターを SomeType としてキャストして、コンストラクターで (Attr 型の) _attr を初期化したい。

Foo コンストラクターの実装:

template<class A, class B>
Foo<A, B>::Foo(A &aInstance):
    _attr(
        (Attr<Foo<A, B> >::SomeType *) aInstance)
{

}

これはコンパイルされません:

エラー: ')' トークンの前にプライマリ式が必要です

そのエラーは、SomeType が認識されなかったかのように、Foo コンストラクター実装のキャスト行を参照しています。

インスタンスができましたが、それでも同じエラーが発生します。

4

5 に答える 5

2
template<class A, class B>
Foo<A, B>::Foo():
    _attr(
        (Attr<Foo<A, B> >::SomeType *) A)
{

}

Aは型であり、それをコンストラクターに渡そうとしています。ここにインスタンスが必要です。

于 2011-07-07T13:18:19.170 に答える
1

0)

(Attr<Foo<A, B> >::SomeType *) A)

その時点で、Aは型名、つまり型の名前であるため、キャストできるものは何もありません。

1)

また、Foo<A,B>は依存してAいるBため、Attr<Foo<A, B> >も依存名です。したがって、型typenameであることをコンパイラに伝えるには、そこが必要です。SomeType

(typename Attr<Foo<A, B> >::SomeType *) somePointer)

2)

さらに、C++ では、通常、C スタイルのキャストよりも C++ のキャストが好まれます。あなたはそれらで多くの間違いを見つけるでしょう。このチュートリアルも参照してください:)

3)

一方で、設計上キャストが必要ですか、それともAttr正確に を指す必要がありFoo<A, B>ますか?

于 2011-07-07T13:21:09.137 に答える
1

まず、Attr クラスは (あなたのスニペットでは) C 型を使用しないため、どこで使用されているか、および C と SomeType の関係を説明する必要があります。

第二に、この行で

Foo<A, B>::Foo():
    _attr(
        (Attr<Foo<A, B> >::SomeType *) A)

A は型であり、オブジェクトではありません。_attr を Foo オブジェクト自体で初期化する必要がある場合は、ポインター this を渡す必要があります。

Foo<A, B>::Foo():
    _attr(
        (Attr<Foo<A, B> >::SomeType *) this)

ただし、この時点では Foo オブジェクトはまだ構築されていないため、Attr コンストラクターでのポインターの操作に注意してください。

于 2011-07-07T13:21:15.957 に答える
0

これは私のために働きます。いくつかのtypedefは、テンプレート化されたコードの意味を少し簡単にするのに役立ちます。

template<class C>
class Attr
{
public:
    class SomeType
    {
        SomeType();
       ~SomeType();
    };

    typedef typename Attr<C>::SomeType ReachIntoSomeType;

    Attr(const SomeType* st) { }
    ~Attr() { }

private:
    Attr();
};

template <class A, class B>
class Foo
{
public:
    Foo(A &aInstance) : _attr(reinterpret_cast<AttrOfFoo::ReachIntoSomeType*>(aInstance))     
    { }

private:
    typedef Attr<Foo> AttrOfFoo;
    AttrOfFoo _attr;
};
于 2011-07-07T15:44:08.013 に答える
0

コンストラクターを次のように変更してみてください。

template<class A, class B>
Foo<A, B>::Foo(A &aInstance):
    _attr(
        (typename Attr<Foo<A, B> >::SomeType *) &aInstance) {}

ポインターが必要なため、インスタンスオブジェクトのアドレスを取得するためにアドレスオブ演算子を追加する必要があります...そうしaInstanceないと、ポインター型ではなく、実質的には参照型になりますオブジェクトへのポインターではなく、オブジェクト自体を (参照によって) 渡します。

于 2011-07-07T13:26:34.263 に答える