C ++ Шаблонная специализация на не конкретном типе (еще один шаблонный класс!) - PullRequest
0 голосов
/ 10 марта 2011

Я портирую некоторый код для использования умных указателей в некоторых местах, и я столкнулся с проблемой со специализацией.Специализировать шаблонную функцию для конкретного типа очень просто, но что если я захочу специализировать конкретный метод для другого шаблонизированного класса (в моем случае, std :: auto_ptr)?Я не могу найти нужные магические слова, чтобы заставить мой компилятор не плакать.

Вот пример кода:

#include <memory> // std::auto_ptr
#include <iostream> // std::cout
class iSomeInterface
{
public:
    virtual void DoSomething() = 0;
};

class tSomeImpl : public iSomeInterface
{
public:
    virtual void DoSomething() { std::cout << "Hello from tSomeImpl"; }
};

template <typename T>
class tSomeContainer
{
public:
    tSomeContainer(T& t) : _ptr(t){}
    iSomeInterface* getInterfacePtr();
private:
    T _ptr;
    // usage guidelines
    tSomeContainer();
};

template <typename T>
iSomeInterface* tSomeContainer<T>::getInterfacePtr()
{
    return _ptr;
}

void testRegularPointer()
{
    tSomeImpl* x = new tSomeImpl();
    tSomeContainer<tSomeImpl*> xx(x);
    xx.getInterfacePtr()->DoSomething();
    delete x;
}
#if 1
// specialize for auto_ptr
template <typename T>
iSomeInterface* tSomeContainer< std::auto_ptr<T> >::getInterfacePtr()
{
    return _ptr.get();
}

void testAutoPtr()
{
    std::auto_ptr<tSomeImpl> y(new tSomeImpl);
    tSomeContainer< std::auto_ptr<tSomeImpl> > yy(y);
    yy.getInterfacePtr()->DoSomething();
}
#else
void testAutoPtr()
{
}
#endif

int main()
{
    testRegularPointer();
    testAutoPtr();
    return 0;
}

Я пытаюсь переопределить tSomeContainer :: getInterfacePtr () метод, когда тип является std :: auto_ptr, но я просто не могу заставить его пойти

Ответы [ 2 ]

1 голос
/ 10 марта 2011

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

Вместо этого вы можете использовать перегруженные шаблоны функций:

namespace ntSomeContainerImpl {
    template <typename T>
    T* getInterfacePtr(T* ptr) { return ptr; }
    template <typename T>
    T* getInterfacePtr(const std::auto_ptr<T>& ptr) { return ptr.get(); }
}

template <typename T>
iSomeInterface* tSomeContainer<T>::getInterfacePtr()
{ return ntSomeContainerImpl::getInterfacePtr( _ptr ); }
1 голос
/ 10 марта 2011

работает ли

template <template<typename> class PtrCtr, typename Ptr>
class tSomeContainer<PtrCtr<Ptr> >
{...};

у вас?

Кажется, я помню, что столкнулся с проблемой, описанной выше, если она также определена для не шаблонных классов.YMMV

...