Невозможно ли вызывать операторы С++ вручную?

Я пытаюсь понять операторы на С++ более тщательно.

Я знаю, что операторы в С++ в основном являются просто функциями. Я не понимаю, как выглядит функция?

Возьмем, например:

int x = 1;
int y = 2;
int z = x + y;

Как переводит последнюю строку? Это:

1. int z = operator+(x,y);

или

2. int z = x.operator+(y);?

Когда я попробовал оба из них, ошибки компилятора. Я называю их неправильными или операторы на С++ не могут быть вызваны напрямую?

Ответы

Ответ 1

Используя С++ standardese, синтаксис вызова функции (operator+(x, y) или x.operator+(y)) работает только для функций оператора:

13.5 Перегруженные операторы [over.oper]

4. Операторские функции обычно не вызываются напрямую; вместо этого они вызывается для оценки операторов, которые они реализуют (13.5.1 - 13.5.7). Они могут быть явно вызваны, однако, используя operator-function-id как имя функции в вызове функции синтаксис (5.2.2). [Пример:

    complex z = a.operator+(b); // complex z = a+b;
    void* p = operator new(sizeof(int)*n);

-end пример]

И для функций оператора требуется хотя бы один параметр, который является типом класса или типом перечисления:

13.5 Перегруженные операторы [over.oper]

6. Функция оператора должна быть либо нестатической функцией-членом или быть нечленой функцией и иметь хотя бы один параметр, тип которого это класс, ссылка на класс, перечисление или ссылка на перечисление.

Это означает, что операторная функция operator+(), которая принимает только int, не может существовать на 13.5/6. И вы, очевидно, не можете использовать синтаксис вызова функции для функции оператора, которая не может существовать.

Ответ 2

Для базовых типов, таких как int, float, double; операторы уже перегружены/предварительно определены, поэтому для этого ничего особенного не может быть сделано. И,

int z = x + y;

- это единственный способ выразить/назвать его.

Для цели интерпретации, фактически оба оператора,

int z = operator+(x,y);
int z = x.operator+(y);

являются истинными (если бы они были перегружены).

Ответ 3

Перегрузки оператора применяются только к объектам и структурам, а не к фундаментальным типам (например, int или float). Если у вас есть класс объектов, например:

  class A {
    A operator+(const A& rhs) {
      return someComputedValue;
    }
  }

то вы действительно можете вызвать myA.operator+(anotherA), и это будет эквивалентно myA + anotherA.

Ответ 4

Вы не можете перегружать двоичные операторы, когда оба аргумента построены в типах. Однако для ваших собственных объектов вы можете их создать.

//Simple struct that behaves like an int.
struct A
{
  int v_;
  explicit A(int i) : v_(i) {}  
  // A member operator so we can write a+b
  A operator+(const A & a ) const { return A( v_ + a.v_); }      
};

// A non-member operator, so we can write 1+a
A operator+(int i, const A & a)
{
   return A(i+a.v_);
}

int main()
{
  A a(1);
  A b(2);

  // Call the member version using its natural syntax    
  A c = a+b;
  //Call the member version using function call syntax
  A d = a.operator+(b);
  // Call the non-member version using the natural syntax
  A e = 1 + b;
  // Call the nonmember version using function call syntax.
  A f = ::operator+(1,b);
}

Ответ 5

Для родных типов операторы не являются функциями. Функционируют только перегруженные операторы. Встроенные операторы встроены - у них нет "функций", они обычно просто компилируются до одной или двух команд сборки, которые было бы безумным, чтобы вызывать функцию.

Таким образом, ни operator+(x, y), ни x.operator+(y) не верны. Я полагаю, что x.operator+(y) менее корректен, потому что типы не struct не могут иметь членов, но я сомневаюсь, что это помогает.

Ответ 6

Как уже упоминалось в комментариях и в других ответах, для основных типов нет operator+. Для классов правильный ответ на вопрос о том, какой из operator+(x,y) по сравнению с x.operator+(y) правильный, "зависит от". В частности, это зависит от того, как было определено operator+. Если он был определен как функция-член, вам нужно использовать x.operator+(y). Если он был определен как глобальная функция, вам нужно использовать operator+(x,y).

Когда компилятор сталкивается с выражением z=x+y;, ваш компилятор достаточно умен, чтобы искать соответствующую форму. Вы не должны ожидать того или другого. Вы должны использовать x+y.