C++ C++;在Pimple成语中,是在类之前还是在成员之前转发声明?

C++ C++;在Pimple成语中,是在类之前还是在成员之前转发声明?,c++,namespaces,forward-declaration,pimpl-idiom,incomplete-type,C++,Namespaces,Forward Declaration,Pimpl Idiom,Incomplete Type,大多数Pimpl示例如下所示: 更新:这两种情况都失败,即使用和不使用名称空间。请参阅R Sahu的答案。类Impl必须使用类名siml // Simple.h #include <memory> class Simple { struct Impl; // WORKS! std::unique_ptr<Impl> impl_; public: Simple(); ~Simple(); int get() con

大多数Pimpl示例如下所示:

更新:这两种情况都失败,即使用和不使用名称空间。请参阅R Sahu的答案。类Impl必须使用类名
siml

// Simple.h
#include <memory>
class Simple {
     struct Impl; // WORKS!
     std::unique_ptr<Impl> impl_;
     public:
     Simple();
     ~Simple();
     int get() const;
};

//main.cpp
#包括“Simple.h”
#包括
int main(){
自动无意义=weired::示例::简单{};

std::cout您可以在类内部和类外部转发声明
Impl
,而不管
Simple
是在命名空间中定义的还是全局定义的

在这两种情况下,
Impl
的实现几乎相同

没有
命名空间
选项1(
Impl
是对等类) .h文件

struct Impl;
class Simple { ... };
class Simple
{
   struct Impl;
   ...
};
namespace weired::example {

   struct Impl;
   class Simple { ... };
}
namespace weired::example {

   class Simple
   {
      struct Impl;
      ...
   };
}
.cpp文件

// Define Impl
struct Impl { ... };

// Define Simple
// Define Impl
struct Simple::Impl { ... };  // Need the Simple:: scope here.

// Define Simple
namespace weired::example {

   // Define Impl
   struct Impl { ... };

   // Define Simple
}
namespace weired::example {

   // Define Impl
   struct Simple::Impl { ... };  // Need the Simple:: scope here.

   // Define Simple
}
选项2(
Impl
是一个嵌套类) .h文件

struct Impl;
class Simple { ... };
class Simple
{
   struct Impl;
   ...
};
namespace weired::example {

   struct Impl;
   class Simple { ... };
}
namespace weired::example {

   class Simple
   {
      struct Impl;
      ...
   };
}
.cpp文件

// Define Impl
struct Impl { ... };

// Define Simple
// Define Impl
struct Simple::Impl { ... };  // Need the Simple:: scope here.

// Define Simple
namespace weired::example {

   // Define Impl
   struct Impl { ... };

   // Define Simple
}
namespace weired::example {

   // Define Impl
   struct Simple::Impl { ... };  // Need the Simple:: scope here.

   // Define Simple
}
使用
命名空间
选项1(
Impl
是对等类) .h文件

struct Impl;
class Simple { ... };
class Simple
{
   struct Impl;
   ...
};
namespace weired::example {

   struct Impl;
   class Simple { ... };
}
namespace weired::example {

   class Simple
   {
      struct Impl;
      ...
   };
}
.cpp文件

// Define Impl
struct Impl { ... };

// Define Simple
// Define Impl
struct Simple::Impl { ... };  // Need the Simple:: scope here.

// Define Simple
namespace weired::example {

   // Define Impl
   struct Impl { ... };

   // Define Simple
}
namespace weired::example {

   // Define Impl
   struct Simple::Impl { ... };  // Need the Simple:: scope here.

   // Define Simple
}
选项2(
Impl
是一个嵌套类) .h文件

struct Impl;
class Simple { ... };
class Simple
{
   struct Impl;
   ...
};
namespace weired::example {

   struct Impl;
   class Simple { ... };
}
namespace weired::example {

   class Simple
   {
      struct Impl;
      ...
   };
}
.cpp文件

// Define Impl
struct Impl { ... };

// Define Simple
// Define Impl
struct Simple::Impl { ... };  // Need the Simple:: scope here.

// Define Simple
namespace weired::example {

   // Define Impl
   struct Impl { ... };

   // Define Simple
}
namespace weired::example {

   // Define Impl
   struct Simple::Impl { ... };  // Need the Simple:: scope here.

   // Define Simple
}

内部类方法仍将在命名空间内工作;您可能只是在.cpp文件中错误地定义了内部类。您得到的实际错误是什么?
struct Simple::Impl{int a,b;};
在Simple.cpp中,而不是
struct Impl{int a,b;}
应该做这项工作。请注意,我不能做嵌套的命名空间。这是C++20东西?@user4581301 C++17东西。@Fureeish-Huh。看起来在某个时候,我在IDE的新项目模板中将默认标准设置为11而不是17。谢谢!修复了。是的,想法是在类中私下转发声明,然后你就不需要保护了
中的Impl类详细说明了
命名空间,使其对客户端不可见。但是在这种情况下,为什么我可以省略
struct Simple::Impl{…}中的简单限定符
如果我的简单类不在名称空间中?所有编译器中都有编译器错误?您是正确的,名称空间大小写和非名称空间大小写是相同的。没有名称空间,我无法再复制成功的编译。一定是某个地方出错了。很抱歉。