为什么子类在C ++中看不到父类的typedef结构?

时间:2012-08-15 17:18:44

标签: c++ templates inheritance name-lookup

我最近遇到了一些C ++代码typedef在父类中编写了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

A.h(编译)

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

B.h(不编译)

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

B.h(编译)

#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 个答案:

答案 0 :(得分:2)

您需要在typename A<Q,Q>::Datum内说B。由于基类是模板,因此其名称是从属名称,在第一阶段不可见,您需要typename来指定名称命名类型(而不是值或模板)。

你也应该失去typedef。 C ++与C的工作方式不同,您应该说:

struct Datum { S x; T y };

答案 1 :(得分:1)

这个

typedef struct {
    S x;
    T y;
}

是不正确的。 typedef需要一个类型和一个“别名”来命名该类型。您可能需要的是

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

没有typedef,这里根本不需要。然后,您需要正确定位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);
};