C++模板部分特化 - 仅专门用于一个成员函数

Rom*_*udl 11 c++ templates partial-specialization

陷入另一个模板问题:

问题:我想在对象是指针的情况下部分地专门化一个容器类(foo),并且我只想专门使用delete-method.应该是这样的:

lib代码

template <typename T>
class foo
{
public:
    void addSome    (T o) { printf ("adding that object..."); }
    void deleteSome (T o) { printf ("deleting that object..."); }
};

template <typename T>
class foo <T *>
{
public:
    void deleteSome (T* o) { printf ("deleting that PTR to an object..."); }
};
Run Code Online (Sandbox Code Playgroud)

用户代码

foo<myclass> myclasses;
foo<myclass*> myptrs;

myptrs.addSome (new myclass());
Run Code Online (Sandbox Code Playgroud)

这导致编译器告诉我myptrs没有一个名为addSome的方法.为什么?

感谢名单.


根据托尼的答案,完全可编辑的东西


LIB

template <typename T>
class foobase
{
public:
    void addSome    (T o) { printf ("adding that object..."); }
    void deleteSome (T o) { printf ("deleting that object..."); }
};


template <typename T>
class foo : public foobase<T>
{ };

template <typename T>
class foo<T *> : public foobase<T *>
{
public:
    void deleteSome (T* o) { printf ("deleting that ptr to an object..."); }
};
Run Code Online (Sandbox Code Playgroud)

用户

foo<int>    fi;
foo<int*>   fpi;

int         i = 13;

fi.addSome (12);            
fpi.addSome (&i);

fpi.deleteSome (12);        // compiler-error: doesnt work
fi.deleteSome (&i);         // compiler-error: doesnt work
fi.deleteSome (12);         // foobase::deleteSome called
fpi.deleteSome (&i);        // foo<T*>::deleteSome called
Run Code Online (Sandbox Code Playgroud)

Kir*_*sky 11

第二个解决方案(正确的)

template <typename T>
class foo
{
public:
    void addSome    (T o) { printf ("adding that object..."); } 
    void deleteSome(T o) { deleteSomeHelper<T>()(o); }
protected:
    template<typename TX> 
    struct deleteSomeHelper { void operator()(TX& o) { printf ("deleting that object..."); } };
    template<typename TX> 
    struct deleteSomeHelper<TX*> { void operator()(TX*& o) { printf ("deleting that PTR to an object..."); } };
};
Run Code Online (Sandbox Code Playgroud)

根据核心问题#727,此解决方案有效.


第一个(不正确的)解决方案:(保留此评论参考它)

你不能只专注于课程的一部分.在您的情况下,最好的方法是重载函数deleteSome如下:

template <typename T>
class foo
{
public:
    void addSome    (T o) { printf ("adding that object..."); }
    void deleteSome (T o) { printf ("deleting that object..."); }
    void deleteSome (T* o) { printf ("deleting that object..."); }
};
Run Code Online (Sandbox Code Playgroud)


Ale*_*tov 10

另一种方法.使用辅助功能deleteSomeHelp.

template <typename T>
class foo {
 public:    
   void addSome    (T o) { printf ("adding that object..."); 
   template<class R>
   void deleteSomeHelp (R   o) { printf ("deleting that object..."); }};
   template<class R>
   void deleteSomeHelp (R * o) { printf ("deleting that PTR to an object..."); }};
   void deleteSome (T o) { deleteSomeHelp(o); }
}    
Run Code Online (Sandbox Code Playgroud)