порядок операндов в перегрузке оператора *

Я пишу класс vec3 для своего игрового физического движка.

Я сделал перегрузку оператора, чтобы позволить мне умножать вектор на скаляр (для масштабирования вектора):

const vec3 operator*( const real n ) const
{
    return vec3(
        m_x * n,
        m_y * n,
        m_z * n
    );
}

Это работает правильно, если я использую правильный порядок в своих вычислениях:

float rImpulse;
vec3 vContactNormal;
...
vec3 vImpulse = vContactNormal * rImpulse;

если я изменяю порядок умножения (например, если я ставлю скаляр первым в вычислении), то компилятору это не нравится, и он выделяет это как ошибку.

Могу ли я обновить свой класс vec3, чтобы порядок умножения не имел значения? Как? (Наверное, хлопну себя по лбу, когда увижу ответ!)

Обновить

Я удалил исходную перегрузку оператора из класса vec3 и поместил следующие две перегрузки оператора вне класса vec3:

const vec3 operator*( const vec3 & v, const real r )
{
    return vec3( 
        v.x() * r, 
        v.y() * r, 
        v.z() * r 
    );
}
const vec3 operator*( const real n, const vec3 & v )
{
    return v * n;
}

person fishfood    schedule 28.07.2012    source источник


Ответы (1)


Вам нужно объявить свободный оператор вне класса (или внутри, как friend):

const vec3 operator*( const real n, vec3 v )
{
    //no need to re-implement, since you already have v * n defined
    return v * n;
}

Причина в том, что при объявлении в качестве члена класса первым оператором неявно является this, так что вы фактически определили vec3 * real.

person Luchian Grigore    schedule 28.07.2012
comment
если оператор находится вне класса, какой эффект будет иметь ключевое слово final const? - person fishfood; 29.07.2012
comment
:) нет проблем! Спасибо за ваш ответ. Я приму ваш ответ после необходимых 13 минут или около того. - person fishfood; 29.07.2012
comment
Есть веские причины, по которым обе версии оператора * должны быть объявлены вне класса. Аргументы в первой позиции обрабатываются иначе, чем аргументы во второй позиции для бинарного оператора, определенного внутри класса. Чтобы избежать этого, объявите симметричные бинарные операторы вне класса. - person jahhaj; 29.07.2012
comment
@jahhaj Не могли бы вы объяснить более точно, как параметры обрабатываются по-разному, пожалуйста? Не могли бы вы, например, добавить ссылку на соответствующую спецификацию C++, если это возможно? - person wip; 16.04.2015