Есть ли какое-либо преимущество для идиомы pimpl с шаблонным классом? - PullRequest
4 голосов
/ 27 сентября 2011

Насколько я понимаю, основным преимуществом идиомы pimpl является скрытие элементов данных в файле реализации вместо заголовка.Однако шаблоны должны быть полностью определены в заголовке, чтобы компилятор мог создавать их экземпляры по требованию.Есть ли в этом случае какое-либо преимущество использования идиомы pimpl для шаблонного класса?

Ответы [ 5 ]

5 голосов
/ 27 сентября 2011

Хотя идиома pimpl на самом деле ничего не скрывает при использовании в шаблонном классе, она позволяет легко писать не-бросающие свопы (хотя в семантике перемещения C ++ 11 это не так важно).*

1 голос
/ 27 сентября 2011

Есть один случай, который не может быть строго идиотом, но достаточно похож, чтобы о нем знать.То есть иметь типобезопасную оболочку шаблона поверх не типизированной версии.

class MapBase
{
   public:
     void* getForKey(const std::string & k);
     void setForKey(const std::string & k, void * v);
     ...
};

template<typename T>
class MyMap
{
  public:
    T* getForKey(const std::string &k) { return (T*)base_.getForKey(k); }
    void setForKey( const std::string &k, const T* v) { base_.setForKey(k, T*v); }
  private:
   MapBase base_;
};

Теперь любое использование MyMap<T> не должно подвергаться воздействию внутренних компонентов MapBase, и вы получаете только одну реализациюкишки этих функций.Я бы также подумал о том, чтобы сделать MapBase абстрактным базовым классом, чтобы сделать разделение еще более сильным.

Как я уже сказал, это не совсем pimpl, но он решает те же проблемы аналогичным образом.

1 голос
/ 27 сентября 2011

В больших проектах, разделение только единиц перевода является достаточной причиной для прыщей. Это работает даже с шаблонами:

// main interface

template <typename> struct MyImpl;

class TheInterface
{
  MyImpl<int> * pimpl;
};

// implementation

#include "MyImpl.hpp" // heavy-weight template library

// TheInterface implementation
0 голосов
/ 27 сентября 2011

это все еще вполне пригодно для использования - рассмотрите автоматический или разделяемый указатель, который является шаблоном и вполне пригоден для решения и реализации PIMPL. лучшее ли это решение зависит от проблемы.

шаблоны должны быть полностью определены в заголовке, чтобы компилятор мог создавать их экземпляры по требованию.

вы можете объявить членов и интерфейс шаблона, затем в файле cpp вашего типа вы можете #include необходимые определения специализаций и использовать их там.

0 голосов
/ 27 сентября 2011

Я думаю, что если вы немного расширите идиому, в некоторых случаях вы можете извлечь из нее хоть немного. В шаблоне не каждая операция обязательно должна зависеть от параметров шаблона. Таким образом, вы можете наследовать от Impl класса, который сам использует идиому pimpl, что-то вроде этого:

struct FooPimpl;

class FooImpl {
  protected:
    FooPimpl* pimpl;
  public:
    void myCommonInterfaceMethod();
};

template <typename T> class Foo : public FooImpl {
  // stuff that depends on T
};

Конечно, это сильно зависит от обстоятельств. Но я вижу, что идиома pimpl работает в контексте класса шаблона.

...