1

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?

5
  • 2
    This doesn't compile with /std:c++17 either. It gives the same expected and self-explanatory error since you have member access into the incomplete type ArrayWrapper. What in the error message is unclear? Commented Jul 27, 2023 at 10:06
  • 1
    Clang 16 gives "error: member access into incomplete type 'ArrayWrapper' void Add() { arrayWrapper->file.Read(); }" which might be more helpful - at the point where arrayWrapper->file.Read() is encountered, the compiler doesn't know anything about ArrayWrapper Commented Jul 27, 2023 at 10:15
  • @TedLyngmo compiles with /std:c++17 for me after fixing the error with file.Read which should be file->Read demo. Commented Jul 27, 2023 at 10:18
  • 1
    @n.m.willseey'allonReddit It seems they made it more strict in C++20 mode. Add /permissive- when compiling in C++17 mode and it fails there too. Commented Jul 27, 2023 at 11:07
  • 3
    MSVC lacks two-phase name lookup without /permissive-, and setting C++20 or C++latest implies /permissive- while setting C++17 does not. Commented Jul 27, 2023 at 11:26

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.