C++ 将pimpl与模板化类和显式实例化模板一起使用

C++ 将pimpl与模板化类和显式实例化模板一起使用,c++,templates,explicit,pimpl-idiom,C++,Templates,Explicit,Pimpl Idiom,当我显式实例化模板时,如何对模板化类使用pimpl 我只需要一个示例代码 我尝试的是: // MyTemplatedClass.h template< class T > class MyTemplatedClass { private: class Impl; Impl* _pimpl; public: void PublicMethod(); } //MyTemplatedClass.h 模板 类MyTemplatedClass { 私人: 类Imp

当我显式实例化模板时,如何对模板化类使用pimpl

我只需要一个示例代码

我尝试的是:

// MyTemplatedClass.h

template< class T >
class MyTemplatedClass
{
private:
    class Impl;
    Impl* _pimpl;

public:
    void PublicMethod();
}
//MyTemplatedClass.h
模板
类MyTemplatedClass
{
私人:
类Impl;
Impl*_pimpl;
公众:
无效方法();
}
我的实现如下:

// MyTemplatedClass.cpp

template< class T >
class MyTemplatedClass<T>::Impl
{
    public:
        void PublicMethod();
}

template <class T>
void MyTemplatedClass<T>::Impl::PublicMethod()
{
    ...
}
//MyTemplatedClass.cpp
模板
类MyTemplatedClass::Impl
{
公众:
无效方法();
}
模板
void MyTemplatedClass::Impl::PublicMethod()
{
...
}
将方法调用转发到实现类:

template< class T >
void MyTemplatedClass<T>::PublicMethod()
{
    _pimpl->PublicMethod();
}
模板
void MyTemplatedClass::PublicMethod()
{
_pimpl->PublicMethod();
}
显式实例化: 使用int和double的示例:

template class MyTemplatedClass< int >;
template class MyTemplatedClass< double >;
模板类MyTemplatedClass;
模板类MyTemplatedClass

但是它似乎不起作用。

模板类的方法总是必须在标题中定义。您不能单独将
MyTemplatedClass.cpp
作为编译单元。您可以做的是
#在
MyTemplatedClass.h
的末尾包含包含方法定义的文件,以便声明和定义至少在文件级别上分开。因此,您的问题可以通过添加

#include "MyTemplatedClass.cpp"
在MyTemplatedClass.h的末尾


我在自己的代码中使用带模板类的pimpls,这样对我来说很有用。您的代码看起来不错-我会使用
std::unique\u ptr
作为pimpl,但我看不出您的操作有任何问题。

这可以回答您的问题,但我怀疑它是否能达到您希望的效果。我怀疑您希望在MyTemplatedClass的范围之外声明模板实现。从模板实现继承而不是将其作为成员变量可能是更好的设计

如果您的编译器不支持外部模板声明,我看不出有一个指向实现的模板指针会增加任何值。无论如何,您都必须在头文件中隐藏您想要隐藏的实现细节

#include <iostream>

template < class T > class MyTemplatedClass {
private:
  template < class U> class Impl {
  public:
     void ImplPublicMethod() {
           std::cout << "Standard implementation" << std::endl;
           }
  };

  Impl<T> * _pimpl;
public:
  MyTemplatedClass() : _pimpl(new Impl<T>) { }
  ~MyTemplatedClass() { delete _pimpl; }
  void publicMethod() {
     _pimpl->ImplPublicMethod();
  }
};

template<> class MyTemplatedClass<int> {
private:
  class Impl {
  public:
     void ImplPublicMethod() {
          std::cout << "Integer specialisation" << std::endl;
     };
 };

 Impl * _pimpl;
public:
  MyTemplatedClass() : _pimpl(new Impl) { }
  ~MyTemplatedClass() { delete _pimpl; }
  void publicMethod() {
     _pimpl->ImplPublicMethod();
  }
};

int main(int argc, char ** argv) {

   MyTemplatedClass<char> charVersion;
   charVersion.publicMethod();

   MyTemplatedClass<int> intVersion;
   intVersion.publicMethod();

   return 0;
}
#包括
模板类MyTemplatedClass{
私人:
模板class Impl{
公众:
void implucMethod(){

当某些东西“似乎不起作用”时,总是准确地告诉我们它是如何“似乎不起作用”的换句话说,你得到了什么错误?当我尝试转发PublicMethod时,编译器没有检测到我的PublicMethod。\u pimpl->应该给我一个可用方法的列表,但是没有人存在。你说的是你的IDE,对吗?IDE和编译器中的代码分析通常是两件不同的事情;如果你的IDE没有向您展示一个方法是可用的,这并不一定意味着如果您在那里使用它,编译器将找不到它。它给出了一个错误:“->PublicMethod”的左边必须指向class/struct/union/generic type 1>MyTemplatedClass.cpp(65):在编译类模板成员函数“void MyTemplatedClass::PublicMethod()时“@user1507569似乎编译器找不到
\u pimpl
的正确定义。请尝试使用
this->
作为前缀-1:模板类的成员函数必须始终在头中定义,除非它们在程序中的某个地方显式实例化。OP正在进行显式实例化,因此这不适用于这里是y。我一定是脑出血了。一个小小的打字错误让编译器很生气。我在问题中写的代码很好用。