Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling primitive operator-functions explicitly in C++

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. 

This on the other hand works -

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! 
  • Is it even possible to invoke operator+ (and other operators) of primitive types (like int) directly?
  • If yes, how?
  • If not, is there a C++ reference verbiage that makes it clear that this is not doable?
like image 471
Vatsan Avatar asked Oct 30 '10 23:10

Vatsan


2 Answers

Firstly, invoking built-in operators as functions will not work simply because the language specification never says that such functions exist. Built-in operators are just operators. There are no implementing functions behind them simply because the language specification never suggests their existence. Function-based implementations are specific to overloaded operators only.

Secondly, during overload resolution the built-in operators are indeed represented by their imaginary function-like counterparts, but the wording that prohibits "explicit" function-like invocation of built-in operators is present in 13.6/1

The candidate operator functions that represent the built-in operators defined in clause 5 are specified in this subclause. These candidate functions participate in the operator overload resolution process as described in 13.3.1.2 and are used for no other purpose.

like image 68
AnT Avatar answered Nov 17 '22 19:11

AnT


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

Can I define an operator overload that works with built-in / intrinsic / primitive types?

No, the C++ language requires that your operator overloads take at least one operand of a "class type" or enumeration type. The C++ language will not let you define an operator all of whose operands / parameters are of primitive types.

For example, you can't define an operator== that takes two char*s and uses string comparison. That's good news because if s1 and s2 are of type char*, the expression s1 == s2 already has a well defined meaning: it compares the two pointers, not the two strings pointed to by those pointers. You shouldn't use pointers anyway. Use std::string instead of char*.

If C++ let you redefine the meaning of operators on built-in types, you wouldn't ever know what 1 + 1 is: it would depend on which headers got included and whether one of those headers redefined addition to mean, for example, subtraction.

C++ Standard §13.5.6

An operator function shall either be a non-static member function or be a non-member function and have at least one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration. It is not possible to change the precedence, grouping, or number of operands of operators. The meaning of the operators =, (unary) &, and , (comma), predefined for each type, can be changed for specific class and enumeration types by defining operator functions that implement these operators. Operator functions are inherited in the same manner as other base class functions.

like image 20
David Titarenco Avatar answered Nov 17 '22 18:11

David Titarenco