компилятор неправильно интерпретирует мой код и добавляет дополнительный аргумент "const" к аргументу - PullRequest
0 голосов
/ 30 марта 2011

Я застрял на ошибке компилятора и не могу найти решение в Интернете (в основном потому, что Google не может обработать синтаксис). Это единственная ошибка, которую я получаю (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 ]

4 голосов
/ 30 марта 2011

Ваш LinkedList<MemberInfo*> должен быть LinkedList<MemberInfo>.

Обратите внимание, что в сообщении об ошибке упоминается MemberInfo *const * - указатель на указатель.

В качестве типа, который вы используете для создания экземпляра шаблона.равно MemberInfo *, T будет MemberInfo *, а функции CreateLinkedList ожидают T const * aka MemberInfo * const *.

Тип, который вы передаете: MemberInfo const * aka const MemberInfo *.

Итак, вы просите компилятор преобразовать из const MemberInfo * в MemberInfo * const *

1 голос
/ 30 марта 2011

вижу пару проблем:

Во-первых, ваша 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*, где это необходимо.

0 голосов
/ 30 марта 2011

Прежде всего, нет никакой разницы между const T и T const.Разрешается добавлять ключевое слово const после типа.Во многих ситуациях это единственный способ точно указать, какая часть типа const.

Вы используете const T* (или T const *).где T равно MemberInfo*:

LinkedList<MemberInfo*>::CreateLinkedList(

Таким образом, полный тип равен MemberInfo * const *.Обратите внимание, что это не то же самое, что const MemberInfo * * (или MemberInfo const * *).

...