g++ 认为我的 class 声明是 "forward declaration"

g++ thinks my class declaration is a "forward declaration"

精简到最低限度,这是我要编译的代码:

template<class T>
class B
{
  protected:

    std::vector<typename T::I> v;

  public:

    template<class... Args>
    void add(Args... args )
    {
      this->v.emplace_back(std::forward<Args>(args)...);
    }

    typename T::I get(int i)
    {
      return this->v[i];
    }
};

class D : public B<D>
{
  public:

    typedef std::string I;
};

如果我实例化 D 并尝试在 g++ 中编译它,它会抱怨:

error: invalid use of incomplete type ‘class D’

std::vector<typename T::I> v;

并添加注释,

note: forward declaration of ‘class D’

class D : public B<D>

如果我尝试 clang++,我会得到一个不同的错误:

error: no type named 'I' in 'D'

std::vector<typename T::I> v;

我确定我只是在做一些愚蠢的事情,但我似乎无法弄明白。

问题是当你写

class D : public B<D>

D 仍然不完整时,您将 class D 作为 B 的模板参数传递。

因此编译器看不到 D::I 因为此时未定义。

g++ 明确地说:"error: invalid use of incomplete type ‘class D’".

clang++ 没有明确说明这一点,但由于这个原因没有找到 I

-- 编辑 --

OP 询问

How do you do what I want to do, then?

我看到的唯一解决方案(不幸的是,这不是一个很好的解决方案)是在另一个 class/struct 中定义您在 B 中需要的内容,比如 C

struct C
 { using I = std::string; };

并从 CB<C>

继承 D
class D : public C, public B<C>
 { };

这种方式 C 是完全定义的,当您将它用作 B 的模板参数时,它也继承自 D