C2027: use of undefined type Foo::Impl

ALL,

class __declspec(dllexport) MyClass
{
protected:
    struct Impl;
    Impl *pimpl;
public:
    Impl &GetStruct() { return pimpl; }
    const std::wstring &GetName() { return pimpl->m_name; };
};

struct MyClass::Impl
{
    std::wstring m_name;
};

Is there a reason why GetName() is throwing the error and GetStruct() does not? And how do I modify the code in order to compile?

TIA!!

The problem is that the C++ parser works from top to bottom. At the end of the MyClass declaration, the nested Impl has not been fully defined. It was declared ("there is a struct Impl") but the full definition ("struct Impl looks as following ...") only comes later. However, in order to generate code for pimpl->m_name, the compiler needs to know more, in particular it needs to know what type m_name is and at what offset to its containing Impl it is located.

In short, you stumbled across a well-known limitation of the PIMPL idiom, namely that you can't use inline functions as you are used to.

C++ Use Of Undefined Type, This translation unit compiles, because the destruction of Foo::impl is left to the destructor Impl<FooImpl>::~Impl<FooImpl> , which is declared  Developer Community for Visual Studio Product family. This site uses cookies for analytics, personalized content and ads. By continuing to browse this site, you agree to this use.

At the point where you request pimpl->m_name, it is not known yet that there's a thing named m_name inside the thing that pimpl points to. Technically, pimpl is a pointer to an incomplete type. It becomes complete when its definition is seen.

So you need to move the definition of GetName out of tye class and to some point after the definition of MyClass::Impl.

Compiler Error C2027, use of undefined type 'type'. A type cannot be used until it is defined. To resolve the error, be sure the type is fully defined before referencing it. Dismiss Join GitHub today. GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.

Actually, I intended to add an MCVE to Ulrichs sufficient answer but while trying to get it running on coliru I found some more issues:

  1. MyClass::GetStruct() has return type Impl& but pimpl after return has type Impl* which is incompatible.

  2. MyClass::GetName() returns const std::string& but is non-const itself. (I'm not sure if this is allowed. I would never do so.)

  3. I added a constructor/destructor because pimpl must be initialized with an instance.

  4. I deleted copy constructor and copy assignment as default implementations would break instances copying the pimpl pointer.

  5. I moved implementation of MyClass::GetName() to solve the issue described by Ulrich.

Fixed sample code:

#include <iostream>
#include <string>

class MyClass
{
protected:
    struct Impl;
    Impl *pimpl;
public:
    MyClass();
    ~MyClass();
    MyClass(const MyClass&) = delete;
    MyClass& operator=(const MyClass&) = delete;
#if 0 // WRONG:
    Impl& GetStruct() { return pimpl; }
    const std::string &GetName() { return pimpl->m_name; }
#else // BETTER:
    Impl& GetStruct() { return *pimpl; }
    const std::string& GetName() const;
#endif // 0

};

struct MyClass::Impl
{
    std::string m_name;
};

MyClass::MyClass(): pimpl(new Impl()) { }

MyClass::~MyClass() { delete pimpl; }

// Implementation after MyClass::Impl is defined
const std::string& MyClass::GetName() const { return pimpl->m_name; }

int main()
{
  MyClass myObj;
  std::cout << "myObj.GetName(): '" << myObj.GetName() << "'\n";
  return 0;
}

Output:

myObj.GetName(): ''

Live Demo on coliru

Note:

I replaced std::w_string by std::string which I consider as irrelevant change. (I've no experience with std::w_string but I guess, without the replacement, it wouldn't change anything.)

compiling error when c++ variadic template class deducing in , I am trying to define a type based on types within a tuple. The code is where foo<Tuple, size_t>() returns a error C2027: use of undefined type 'std::​tuple_element<& I,T>' I doubt if it is a compiler implementation error. @CroCo. You already answered you question yourself. You have a QMenuBar *menuBar pointer that you want to de-reference. The compiler cannot do it if the declaration of QMenuBar is unknown.

class declaration - C++ Forum, this class uses an instance of PortConnection. Error 1 error C2027: use of undefined type 'bluecard::ioport::PortConnection' void foo( class bar& ); // "bar" doesn't need to be forward declarated. typed in a way which include private and implementation defined behaviour in their type (as type parameter  When making a forward declaration to a function, the compiler has everything it needs in order to parse code which invokes that function: the name of the function, the type returned, the number of arguments, and the type of each argument.

cpp-docs/cpp-conformance-improvements.md at master , The following example shows how to use the new std::identity (defined in <​functional>) #include <chrono> class Foo { std::chrono::milliseconds::duration TotalDuration{}; }; but fails under /std:c++17 with "error C2027:use of undefined type 'A<T>'": The implementation divergence is because of a regression in the C++  Dismiss Join GitHub today. GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.

C++ class use of undefined type - c++ - android, the top it still throws off those errors error C2027: use of undefined type 'foo' class foo; Smth like this: class myclass; typedef boost::shared_ptr<myclass> pmyclass; type is just a struct with one member; I use it to hide the implementation. Dismiss Join GitHub today. GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.

Comments
  • Impl and Foo are unrelated!
  • @CinCout, sorry I fixed the code. Any idea?
  • Impl &GetStruct() { return pimpl; } is a compiler error, presumably it should be Impl &GetStruct() { return *pimpl; }