C ++ Unary - перегрузка оператора не будет компилироваться - PullRequest
4 голосов
/ 27 апреля 2010

Я пытаюсь создать перегруженный унарный оператор, но не могу получить код для компиляции. Сокращенная версия кода выглядит следующим образом: -

class frag
{
    public:

        frag myfunc  (frag oper1,
                      frag oper2);
        frag myfunc2  (frag oper1,
                      frag oper2);

        friend frag operator + (frag &oper1,
                                frag &oper2);

        frag operator - ()
        {
            frag f;
            f.element = -element;
            return f;
        }

    private:

        int element;

};

frag myfunc (frag oper1, frag oper2)
{
    return oper1 + -oper2;
}

frag myfunc2 (frag oper1, frag oper2)
{
    return oper1 + oper2;
}

frag operator+ (frag &oper1, frag &oper2)
{
    frag innerfrag;
    innerfrag.element = oper1.element + oper2.element;
    return innerfrag;
}

Компилятор сообщает ...

/home/brian/Desktop/frag.hpp: In function ‘frag myfunc(frag, frag)’:
/home/brian/Desktop/frag.hpp:41: error: no match for ‘operator+’ in ‘oper1 + oper2.frag::operator-()’
/home/brian/Desktop/frag.hpp:16: note: candidates are: frag operator+(frag&, frag&)

Кто-нибудь может подсказать, что мне здесь делать?

Ответы [ 4 ]

7 голосов
/ 27 апреля 2010

Уст-корректность

Это должно быть

 frag operator+ (const frag &oper1, const frag &oper2);

, иначе операнды не могут быть временными, например, возвращаемое значение operator-

А унарный минус скорее должен быть:

frag operator - () const;

, поскольку он не должен изменять операнд.

3 голосов
/ 27 апреля 2010

У вас нет operator+, который может работать с временными. Временные значения не могут быть переданы как неконстантные ссылки.

Измените подпись вашего operator+ на:

frag operator + (const frag &oper1, const frag &oper2);
1 голос
/ 27 апреля 2010

Хотя на ваш вопрос уже был получен достаточно хороший ответ, я думаю, стоит упомянуть еще один момент о вашем коде. Прямо сейчас у вас есть следующие объявления:

class frag
{
    public:

        frag myfunc  (frag oper1,
                      frag oper2);
        frag myfunc2  (frag oper1,
                      frag oper2);

... и у вас есть следующие функции:

frag myfunc (frag oper1, frag oper2)
{
    return oper1 + -oper2;
}

frag myfunc2 (frag oper1, frag oper2)
{
    return oper1 + oper2;
}

Я предполагаю, что вы предполагали, что эти две функции реализуют функции-члены, которые вы объявили в frag - но они этого не делают. Вместо этого у вас есть две функции-члена, которые объявлены никогда не определенными, и эти две глобальные функции имеют одинаковые имена. Чтобы они были функциями-членами, которые вы объявили, вам нужно изменить объявление на что-то вроде:

frag frag::myfunc(frag oper1, frag oper2) { 
    return oper1 + -oper2;
}

frag frag::myfunc2(frag oper1, frag oper2) { 
    return oper1 + oper2;
}

С другой стороны, они на самом деле тоже не имеют никакого смысла в этом смысле - в частности, в качестве функций-членов они обычно вызываются как-то так: a.myfunc(b,c); Они оба действительно написаны как глобальные функции хотя - в качестве функций-членов они обычно принимают только один параметр и используют this в качестве первого параметра:

frag frag::myfunc1(frag oper) { 
    return *this + -oper;
}
frag frag::myfunc2(frag oper) { 
    return *this + oper;
}

Конечно, это может быть просто случайный побочный эффект от попытки уменьшить исходный код до минимума, необходимого для публикации. Если это так, пожалуйста, не стесняйтесь игнорировать весь этот "ответ" ....

0 голосов
/ 27 апреля 2010

Ответ уже дан (аргументы const), но я хотел бы отметить, что Visual C ++ 9 (VS-2008) действительно скомпилирует вышеприведенное без предупреждения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...