【问题标题】:C++ Template specialization on a non-concrete type (another template class!)非具体类型的 C++ 模板特化(另一个模板类!)
【发布时间】:2011-03-09 22:24:35
【问题描述】:

我正在移植一些代码以在某些地方使用智能指针,但我遇到了专业化问题。在具体类型上专门化模板函数非常简单,但是如果我想在另一个模板化类(在我的例子中是 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;
}

当类型为 std::auto_ptr 时,我正在尝试覆盖 tSomeContainer::getInterfacePtr() 方法,但我就是做不到

【问题讨论】:

  • @Andy T:C++0x 的 unique_ptr 对我来说还不是一个选项,它会有同样的问题
  • 检查boost::scoped_ptrboost::shared_ptr

标签: c++ templates specialization


【解决方案1】:

您不能部分特化类模板的单个成员。 (您可以对整个类模板进行部分特化,除了一个成员外,其他定义相同,但这通常不好玩。)

相反,您可以使用重载的函数模板:

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 ); }

【讨论】:

  • 谢谢!我怀疑这是不可能的,感谢您提供了一个非常有用的解决方法
【解决方案2】:

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

为你工作?

如果它也为非模板类​​定义,我似乎记得遇到了上述问题。 YMMV

【讨论】:

  • 我认为他只需要为单个模板专门化它(示例中为auto_ptr),因此您不需要模板模板参数。
  • 这种工作除了我必须将整个 tSomeContainer 类内容复制/粘贴到 {...};也就是说,如果我只是在 {...} 中添加自己的 ::getInterfacePtr() 定义,那么我将丢失之前声明的构造函数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-16
  • 1970-01-01
  • 1970-01-01
  • 2017-07-18
  • 1970-01-01
相关资源
最近更新 更多