开发者

compiler misinterprets my code and adds an extra "const" to argument

开发者 https://www.devze.com 2023-02-20 14:14 出处:网络
I\'m stuck on a compiler error and I can\'t seem to find a solution online (mainly because google can\'t handle the syntax). This is the one and only error I\'m getting (MVS 2005).

I'm stuck on a compiler error and I can't seem to find a solution online (mainly because google can't handle the syntax). This is the one and only error I'm getting (MVS 2005).

error C2664: 'LinkedList<T>::CreateLinkedList' : cannot convert parameter 2  
from 'const MemberInf开发者_JAVA百科o *' to 'MemberInfo *const *'  memberdata.cpp  59

The error points to this piece of code.

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

    return NULL;
}

The relevant pieces of code in this are:

MemberInfo class

// 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 class

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

};

I'm quite stuck. I don't understand why the compiler thinks that my argument for the function CreateLinkedList is MemberInfo *const *rather than how I declared it as const MemberInfo* (or const T* actually).

Any help ideas?

Thanks!


Your LinkedList<MemberInfo*> should be LinkedList<MemberInfo>.

Notice that the error message mentions MemberInfo *const * - a pointer to a pointer.

As the type you use to instantiate the template is a MemberInfo *, T will be MemberInfo * and the CreateLinkedList functions expects a T const * aka a MemberInfo * const *.

The type you pass is a MemberInfo const * aka const MemberInfo *.

So, you're asking the compiler to convert from const MemberInfo * to MemberInfo * const *


I see a couple problems:

First, your MemberInfo::CompareByTime() function is written wrong. The way you have written it throws away any type checking the compiler can do. Better would be:

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

Second, pass the comparison function into your linked list as a template parameter:

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

Third, there's no reason to hide the constructor and wrap it in a static function that returns the superclass' pointer. C++ will automatically convert an object's pointer to a pointer to its superclass when needed. Also, you should be passing the contained values around by reference (instead of pointer) and store them by value when possible; if you want your container to store pointers, then just set T to a pointer type. So your construction simplifies to:

protected:
    T m_ptValue;

public:
    LinkedList(const T& ptVal);

Finally, your code for MemberData::CreateLinkedList is broken. It always returns NULL. That is, from the outside it looks like it never creates a linked list. Also, the this-> does nothing. What you should have is:

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

Though it's probably good practice to define typedef LinkedList<MemberInfo*, MemberInfo::CompareByTime> LinkedListType; in MemberData, which lets us write:

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

Note that the return value will be typecast to ILinkedList* automatically where needed.


First of all, there is no difference between const T and T const. It is allowed to add the const keyword after the type. In many situations that is the only way to exactly specify what part of the type const is.

You are using const T* (or T const *). where T is MemberInfo*:

LinkedList<MemberInfo*>::CreateLinkedList(

So the full type is MemberInfo * const *. Note that this is not the same as const MemberInfo * * (or MemberInfo const * *).

0

精彩评论

暂无评论...
验证码 换一张
取 消