编译器误解了我的代码并为参数添加了一个额外的“const”

时间:2011-03-30 11:12:28

标签: c++ templates linked-list function-pointers

我遇到了编译器错误,我似乎无法在线找到解决方案(主要是因为谷歌无法处理语法)。这是我唯一得到的错误(MVS 2005)。

error C2664: 'LinkedList<T>::CreateLinkedList' : cannot convert parameter 2  
from 'const MemberInfo *' to 'MemberInfo *const *'  memberdata.cpp  59

错误指向这段代码。

ILinkedList*
MemberData::CreateLinkedList()
{
    const MemberInfo* mi = this->get(FIRST);
    LinkedList<MemberInfo*>::CreateLinkedList(
        MemberInfo::CompareByTime,
        mi);

    return NULL;
}

相关的代码片段是:

MemberInfo类

// MemberInfo declaration
class
MemberInfo
{
    public:
        static int
        CompareByTime(
            const void* mi1,
            const void* mi2);
};

// MemberInfo implementation
int
MemberInfo::CompareByTime(
    const void* mi1,
    const void* mi2)
{
    if ( mi1 == NULL || mi2 == NULL )
        return 0;

    if ( ((MemberInfo*)mi1)->m_Time > ((MemberInfo*)mi2)->m_Time )
        return 1;
    if ( ((MemberInfo*)mi2)->m_Time > ((MemberInfo*)mi1)->m_Time )
        return -1;

    return 0;
}

LinkedList类

typedef int (*ComparatorFcn)(const void*, const void*);

template <class T>
class LinkedList
    : public ILinkedList
{
    private:
    protected:
        const T*
        m_ptValue;

        ComparatorFcn
        m_pCompFcn;

        LinkedList(
            const T* ptVal,
            ComparatorFcn func);

    public:
        static ILinkedList*
        CreateLinkedList(
            ComparatorFcn func, 
            const T* ptVal)
        {
            LinkedList<T>* t = new LinkedList<T>(ptVal, func);

            return t;
        }

        virtual
        ~LinkedList();

        LinkedList<T>*
        AddLink(
            T* pLink);

        virtual bool
        Remove();

        virtual bool
        RemoveLink(
            ILinkedList* pLink);

};

我很困惑。我不明白为什么编译器认为我的函数CreateLinkedList的参数是MemberInfo *const *而不是我如何将它声明为const MemberInfo*(或const T*实际上)。

有任何帮助提示吗?

谢谢!

3 个答案:

答案 0 :(得分:4)

您的LinkedList<MemberInfo*>应为LinkedList<MemberInfo>

请注意,错误消息提到MemberInfo *const * - 指向指针的指针。

由于用于实例化模板的类型为MemberInfo *,因此T为MemberInfo *CreateLinkedList函数需要T const *MemberInfo * const *

您传递的类型是MemberInfo const *又名const MemberInfo *

所以,你要求编译器从const MemberInfo *转换为MemberInfo * const *

答案 1 :(得分:1)

我发现了几个问题:

首先,您的MemberInfo::CompareByTime()函数写错了。你编写它的方式会抛弃任何检查编译器可以执行的类型。更好的是:

int MemberInfo::CompareByTime(const MemberInfo& mi1, const MemberInfo& mi2)
{
    if(mi1.m_Time > mi2.m_Time)
        return 1;
    if(mi1.m_Time < mi2.m_Time)
        return -1;
    return 0;
}

其次,将比较功能作为模板参数传递到链接列表中:

template <class T, int (*CompFcn)(const T&, const T&)>
class LinkedList: public ILinkedList

第三,没有理由隐藏构造函数并将其包装在返回超类'指针的静态函数中。 C ++会在需要时自动将对象的指针转换为指向其超类的指针。此外,您应该通过引用(而不是指针)传递包含的值,并在可能的情况下按值存储它们;如果您希望容器存储指针,那么只需将T设置为指针类型即可。因此,您的构造简化为:

protected:
    T m_ptValue;

public:
    LinkedList(const T& ptVal);

最后,MemberData::CreateLinkedList的代码被破坏了。它总是返回NULL。也就是说,从外部看起来它永远不会创建链表。此外,this->什么都不做。你应该拥有的是:

LinkedList<MemberInfo*, MemberInfo::CompareByTime>* MemberData::CreateLinkedList()
{
    return new LinkedList<MemberInfo*, MemberInfo::CompareByTime>(get(FIRST));
}

虽然在typedef LinkedList<MemberInfo*, MemberInfo::CompareByTime> LinkedListType;中定义MemberData可能是一种很好的做法,这可以让我们写一下:

MemberData::LinkedListType* MemberData::CreateLinkedList()
{
    return new LinkedListType(get(FIRST));
}

请注意,返回值将在需要时自动强制转换为ILinkedList*

答案 2 :(得分:0)

首先,const TT const之间没有区别。允许在类型后面添加const关键字。在许多情况下,这是准确指定const类型的哪一部分的唯一方法。

您正在使用const T*(或T const *)。其中TMemberInfo*

LinkedList<MemberInfo*>::CreateLinkedList(

所以完整类型是MemberInfo * const *。请注意,这与const MemberInfo * *(或MemberInfo const * *)不同。