c++ - g++ 认为我的类声明是 "forward declaration"

标签 c++ templates variadic-templates crtp

<分区>

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

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>

你通过了类(class) D作为 B 的模板参数什么时候D仍然不完整。

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

g++ 明确指出:“错误:无效使用不完整类型‘class D’”。

clang++ 没有明确说明但没有找到 I出于这个原因。

-- 编辑 --

OP 要求

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

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

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

并继承D来自 CB<C>

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

这边C已完全定义,当您将其用作 B 的模板参数时, 也继承自 D .

关于c++ - g++ 认为我的类声明是 "forward declaration",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56693195/

相关文章:

c++ - 在 Windows 上编译 gcc 4.7

c++ - C++ 中的 Windows LDAP 身份验证

c++ - 调整二维 vector 的内部尺寸

c++ - 在 struct C++ 中使用 char* 或 char []

c++ - 模板特化和继承

c++ - 使用 C++11 的 Clang 类型转换具有不明确的编译器行为

c++ - boost::range::join 一个自定义调用中的多个范围

c++ - 模板化函数指针

c++ - 使用可变参数模板的特化作为模板参数

c++ - 强制执行所有&&?