0

最近、親クラスでtypedef編集されたC++ コードに出くわしました。structただし、マークされていなくても、子クラスでは使用できないようですprivate(だったprotected)。この失敗を示す最小限の実例 (以下) を以下に作成しました。私はすべてを公開しましたが、それでも失敗します。与えられたエラーは(を使用してg++)です:

B.h:8: error: expected ',' or '...' before '&' token
B.h.8: error: ISO C++ forbids declartion of 'Datum' with no type

ああ(コンパイル)

template<typename S, typename T> class A {
public:
    typedef struct {
        S x;
        T y;
    } Datum;
};

Bh (コンパイルしない)

#include "A.h"
template<typename Q> class B : public A<Q, Q> {
public:
    void output(const Datum& dat);
};

Bh (コンパイル)

#include "A.h"
template<typename Q> class B : public A<Q, Q> {
public:
    typedef struct {
        Q x;
        Q y;
    } Datum;
    void output(const Datum& dat);
};

B.hの最初のバージョンがコンパイルされないのはなぜですか? 2番目のものは安全な代替手段ですか? これを処理するためのより良い(より簡潔または慣用的な)方法はありますか?

4

2 に答える 2

2

typename A<Q,Q>::Datum内部で言う必要がありますB。ベースはテンプレートであるため、その名前は従属名であり、最初のフェーズでは表示されません。またtypename、名前が (値やテンプレートではなく) タイプを示すように指定する必要があります。

も失う必要がありtypedefます。C++ は C とは異なる動作をするため、次のように言う必要があります。

struct Datum { S x; T y };
于 2012-08-15T17:22:32.573 に答える
1

これ

typedef struct {
    S x;
    T y;
}

は不正です。typedefタイプとそのタイプに名前を付けるための「エイリアス」が必要です。おそらく必要なのは

template<typename S, typename T> 
class A {
 public:
    struct Datum { S x; T y; };
};

ここではまったく必要ありません。Datum次に、次のように名前を適切に修飾する必要がありますtypename A<Q,Q>::Datum

#include "A.h"
template<typename Q> 
class B : public A<Q, Q> {
 public:
    void output(const typename A<Q,Q>::Datum& dat);
};
于 2012-08-15T17:22:48.877 に答える