Most Pimpl examples look as follows:
UPDATE: both cases fail, i.e. with and without namespaces. See answer from R Sahu at https://stackoverflow.com/a/57103016/2712726 . class Impl must be qualified with class name Simpl
// Simple.h
#include <memory>
class Simple {
struct Impl; // WORKS!
std::unique_ptr<Impl> impl_;
public:
Simple();
~Simple();
int get() const;
};
But this seems to fail in the real world where you would use namespaces. When namespaces are present, then the forward declaration has to be moved before the class declaration. Can anyone explain why?
// Simple.h but now with name spaces
namespace weired::example {
struct Impl; // OK! forwad declaration must go here
class Simple {
//struct Impl; // ERROR! incomplete type in ctor definition
std::unique_ptr<Impl> impl_;
public:
Simple();
~Simple();
int get() const;
};
}
I have tested this with gcc9
and clang8
with -std=c++11
up to c++2a
.
Just for completeness, here are the Simple.cpp and main.cpp files so you can run the example yourself:
// Simple.cpp
#include "Simple.h"
namespace weired::example {
struct Impl {int a,b;};
Simple::Simple() : impl_(new Impl{3,4}) {}
Simple::~Simple() = default;
int Simple::get() const
{
return impl_->a;
}
}
and
// main.cpp
#include "Simple.h"
#include <iostream>
int main () {
auto nonsense = weired::example::Simple{};
std::cout << nonsense.get() << '\n';
}