Вызов примитивных оператор-функций явно в C ++ - PullRequest
7 голосов
/ 31 октября 2010
int a, b, c; 

//do stuff. For e.g., cin >> b >> c; 

c = a + b;          //works 
c = operator+(a,b); //fails to compile, 'operator+' not defined. 

Это с другой стороны работает -

class Foo
{
 int x; 
public:
 Foo(int x):x(x) {} 

 Foo friend operator+(const Foo& f, const Foo& g)
 {
  return Foo(f.x + g.x); 
 }

};    

Foo l(5), m(10); 

Foo n = operator+(l,m); //compiles ok! 
  • Можно ли даже напрямую вызывать оператор + (и другие операторы) примитивных типов (например, int)?
  • Если да, то как?
  • Если нет, то есть ли справочное слово C ++, которое дает понять, что это невозможно?

Ответы [ 2 ]

8 голосов
/ 31 октября 2010

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

Во-вторых, при разрешении перегрузки встроенные операторы действительно представлены своими воображаемыми аналогичными по функциям аналогами, но формулировка, которая запрещает "явный «функциональный вызов встроенных операторов» представлен в 13.6 / 1

. Функции-кандидаты, представляющие встроенные операторы, определенные в разделе 5, определены в этом подпункте.Эти функции-кандидаты участвуют в процессе разрешения перегрузки оператора, как описано в 13.3.1.2 , и не используются ни для каких других целей .

2 голосов
/ 31 октября 2010

С http://www.parashift.com/c++-faq-lite/intrinsic-types.html

Можно ли определить перегрузку оператора, которая работает со встроенными / встроенными / примитивными типами?

Нет, язык C ++ требует, чтобы перегрузки вашего оператора требуют как минимум один операнд типа "класс" или тип перечисления. Язык C ++ не позволит вам определить оператор все чьи операнды / параметры примитивных типов.

Например, вы не можете определить оператор ==, который занимает два символа * и использует сравнение строк. Это хорошо новости, потому что, если s1 и s2 имеют тип char *, выражение s1 == s2 уже имеет четко определенное значение: это сравнивает два указателя, а не два строки, на которые указывают эти указатели. Вы не должны использовать указатели в любом случае. использование std :: string вместо char *.

Если C ++ позволяет переопределить значение операторы на встроенных типах, вы никогда не узнает, что такое 1 + 1: это будет зависеть от того, какие заголовки включен ли один из тех заголовки переопределяют дополнение к значению, например, вычитание.

C ++ Стандарт §13.5.6

Операторная функция должна быть либо нестатической функцией-членом, либо функцией, не являющейся членом, и иметь как минимум один параметр, тип которого является классом, ссылкой на класс, перечислением или ссылкой на перечисление. Невозможно изменить приоритет, группировку или количество операндов операторов. Значение операторов =, (унарный) & и (запятая), предварительно определенных для каждого типа, может быть изменено для конкретного класса и перечислимых типов путем определения операторных функций, которые реализуют эти операторы. Функции оператора наследуются так же, как и другие функции базового класса.

...