代码之家  ›  专栏  ›  技术社区  ›  Robin Holenweger

为什么有时需要使用模板类型作为指针时,使用模板类型会出现错误C2768?

  •  0
  • Robin Holenweger  · 技术社区  · 7 年前

    我有一个类CMyObject,它有一些getter函数来访问各种成员(例如,类型为CTheValueHolder的成员),而这些成员又有一个setter,每个成员都有一个双值。此调用链需要应用于列表中CMyObject类型的所有项,访问的类及其setter函数在整个代码中随机更改。为了保持代码简短,我想使用一种方法,在这种方法中,我可以将getter函数全部传递给CMyObject实例上的另一个对象(CTheValueHolder)、要在该对象上执行的函数和要设置的值。

    代码如下所示:

    // header
    class CMyService
    {
        template <typename T> void ApplyToList(T* (CMyObject::*getMember)(), void (T::*memberFunction)(double), double iNewValue);
    }
    
    // implementation
    template <typename T>
    void CMyService::ApplyToList<T>(T* (CMyObject::*getMember)(), void (T::*memberFunction)(double), double iNewValue)
    {
        std::list<CMyObject*>myList = GetList();
        std::list<CMyObject*>::iterator endIter = myList.end();
        for (std::list<CMyObject*>::iterator iter = myList.begin();  iter != endIter; iter++)
        {
            if (*iter)
            {
                (((*iter)->*getMember)->*memberFunction)(iNewValue);
            }
        }
    }
    

    CMyObject::*getMember可能如下所示:

    CTheValueHolder* CMyObject::GetTheValueHolder()
    {
        return m_pTheValueHolder;
    }
    

    价值持有人可定义为:

    class CTheValueHolder
    {
        // ....
        void SomeValueSetter(double fNewValue);
        // ....
    }
    

    因此:

    // call from within CMyService
    void CMyService::SomeFunction()
    {
        // ....
        double fSomeNewValue = 123.456;
        ApplyToList<CTheValueHolder>(&CMyObject::GetTheValueHolder, &CTheValueHolder::SomeValueSetter, fSomeNewValue);
        // ....
    }
    

    这样,我得到了错误C2768:“CMyService::ApplyToList”:显式模板参数的非法使用。 有什么想法可以解释为什么以及如何做到这一点吗? 顺便说一句:我目前一直在使用VS2010,所以我没有完整的C++11可用。

    1 回复  |  直到 7 年前
        1
  •  1
  •   oisyn    7 年前

    模板函数的越界定义错误。如果在 模板名称 (例如 <T> 在里面 CMyService::ApplyToList<T> ),您正在指定专门化。在本例中是部分专门化,因为专门化仍然具有模板参数。并且不能部分地专门化函数。

    template<class T> void Foo(); // declaration
    
    // Don't do this:    
    template<class T> void Foo<T>() { /* implementation */ }
    
    // Do this:
    template<class T> void Foo() { /* implementation */ }
    //                       ^^^ Note the missing <T>