使用模板的C++代码在C++20中无法编译,但在C++17中是可以的。

huangapple go评论101阅读模式
英文:

The C++ code that using templates doesn't compile in c++ 20, but was ok in c++ 17

问题

我有一些遗留代码,我想将其升级到C++20。该代码在C++17中编译没有任何问题,但如果我切换到C++20就会失败。我尽可能简化了代码,请看一下这个例子。我在Windows上使用Visual Studio 2022。

以下是错误消息:

error C2027: use of undefined type 'ArrayWrapper'
message : see declaration of 'ArrayWrapper'
message : see reference to class template instantiation 'ArrayClass<T>' being compiled

我在Stack Overflow和C++文档中查找过,但无法弄清楚在C++20中这段代码有什么问题。有人能解释如何解决这个问题吗?谢谢!

英文:

I have some legacy code that I want to upgrade to c++20. The code compiles in c++17 without any issues but fails if I switch to C++20. I simplified the code as much as possible, please look at the example. I am using Visual Studio 2022 on Windows



class MyFile
{
public:
	void Read(){ }
};

class ArrayWrapper;

class BaseClass
{
public:
	ArrayWrapper* arrayWrapper;
};

template &lt;class T&gt; class ArrayClass : public BaseClass
{
public:
	void Add()
	{
		arrayWrapper-&gt;file.Read();
	}
};


class ArrayWrapper
{
public:
	ArrayWrapper(): file(new MyFile()){ }
	~ArrayWrapper() { delete file; }
	MyFile* file;
	ArrayClass&lt;int&gt; Array{};
	void Update()
	{
		Array.Add();
	}
};

int main()
{
	ArrayWrapper wrapper;
	wrapper.Update();
}

And this is the error message that I am getting:

error C2027: use of undefined type &#39;ArrayWrapper&#39;
message : see declaration of &#39;ArrayWrapper&#39;
message : see reference to class template instantiation &#39;ArrayClass&lt;T&gt;&#39; being compiled

I did look on the stack overflow and in the C++ docs but couldn't figure out what is wrong with this code in C++ 20
Can someone explain how to fix this issue, please?

答案1

得分: 1

ArrayClass::Add的定义移动到ArrayWrapper之后。

在类模板的定义之后,方法和整个ArrayClass<int>被实例化,此时ArrayWrapper还没有完全定义。

如果ArrayClass不是一个模板,你将会得到相同的错误。

class MyFile
{
public:
    void Read(){ }
};

class ArrayWrapper;

class BaseClass
{
public:
    ArrayWrapper* arrayWrapper;
};

template <class T> class ArrayClass : public BaseClass
{
public:
    void Add();
};


class ArrayWrapper
{
public:
    ArrayWrapper(): file(new MyFile()){ }
    ~ArrayWrapper() { delete file; }
    MyFile* file;
    ArrayClass<int> Array{};
    void Update()
    {
        Array.Add();
    }
};

template <class T> 
void ArrayClass<T>::Add()
{
    arrayWrapper->file->Read();
}

int main()
{
    ArrayWrapper wrapper;
    wrapper.Update();
}

另外,应该是arrayWrapper->file->Read();file是一个指针。

英文:

Move ArrayClass::Add definition after ArrayWrapper.

The method and the whole ArrayClass&lt;int&gt; is instantiated right after the definition of the class template, at which point ArrayWrapper is still not fully defined.

You would get the same error if ArrayClass was not a template.

class MyFile
{
public:
    void Read(){ }
};

class ArrayWrapper;

class BaseClass
{
public:
    ArrayWrapper* arrayWrapper;
};

template &lt;class T&gt; class ArrayClass : public BaseClass
{
public:
    void Add();
};


class ArrayWrapper
{
public:
    ArrayWrapper(): file(new MyFile()){ }
    ~ArrayWrapper() { delete file; }
    MyFile* file;
    ArrayClass&lt;int&gt; Array{};
    void Update()
    {
        Array.Add();
    }
};

template &lt;class T&gt; 
void ArrayClass&lt;T&gt;::Add()
{
    arrayWrapper-&gt;file-&gt;Read();
}

int main()
{
    ArrayWrapper wrapper;
    wrapper.Update();
}

Also, it should be arrayWrapper-&gt;file-&gt;Read(); file is a pointer.

huangapple
  • 本文由 发表于 2023年7月27日 18:03:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76778627.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定