Как я могу использовать 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 >;
Но это не похоже на работу.
Это ответило бы на ваш вопрос, но я сомневаюсь, что оно делает то, что вы надеялись достичь. Я подозреваю, что вы захотите объявить реализацию шаблона вне области 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;
}
Методы шаблонного класса всегда должны быть определены в заголовке. Вы не можете иметь MyTemplatedClass.cpp
как сборник самостоятельно. Что вы можете сделать, это #include
файл, содержащий определения методов в конце MyTemplatedClass.h
так что объявление и определение по крайней мере разделены на уровне файла. Таким образом, ваша проблема может быть решена путем добавления
#include "MyTemplatedClass.cpp"
в конце MyTemplatedClass.h
,
Я использую pimpls с шаблонными классами в своем собственном коде, это работает для меня таким образом. Ваш код выглядит правильно — я бы использовал std::unique_ptr
для прыщей, но я не вижу никаких проблем с тем, как ты это делаешь.