英文:
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 <class T> class ArrayClass : public BaseClass
{
public:
void Add()
{
arrayWrapper->file.Read();
}
};
class ArrayWrapper
{
public:
ArrayWrapper(): file(new MyFile()){ }
~ArrayWrapper() { delete file; }
MyFile* file;
ArrayClass<int> 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 'ArrayWrapper'
message : see declaration of 'ArrayWrapper'
message : see reference to class template instantiation 'ArrayClass<T>' 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<int>
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 <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();
}
Also, it should be arrayWrapper->file->Read();
file
is a pointer.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论