1

当我显式实例化模板时,如何将 pimpl 用于模板类?

我只需要一个示例代码。

我尝试过的是:

// MyTemplatedClass.h

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

public:
    void PublicMethod();
}

我的实现如下:

// MyTemplatedClass.cpp

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

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

转发方法调用到实现类:

template< class T >
void MyTemplatedClass<T>::PublicMethod()
{
    _pimpl->PublicMethod();
}

显式实例化:使用 int 和 double 的示例:

template class MyTemplatedClass< int >;
template class MyTemplatedClass< double >;

但这似乎不起作用。

4

2 回答 2

1

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

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

#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;
}
于 2013-08-13T08:50:26.000 回答
-1

模板类的方法总是必须在头文件中定义。您不能单独拥有一个MyTemplatedClass.cppas 编译单元。您可以做的是#include在末尾包含方法定义的文件,MyTemplatedClass.h以便声明和定义至少在文件级别分开。所以你的问题可以通过添加来解决

#include "MyTemplatedClass.cpp"

在结束时MyTemplatedClass.h

我在自己的代码中使用带有模板类的 pimpls,它对我有用。您的代码看起来正确 - 我会使用 a std::unique_ptrfor pimpl,但我认为您的操作方式没有任何问题。

于 2013-08-13T08:16:15.477 回答