views:

63

answers:

2
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?
+1  A: 

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.

David Titarenco
I understand this. I'm not trying to overload a primitive operator. I'm merely trying to invoke a primitive operator by calling it's function-operator name.
Vatsan
@Vatsan: `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.` - that's a pretty clear requirement.
David Titarenco
@David - It's clear that I'm prohibited from declaring a new operator function that doesn't meet these requirements. It doesn't tell me why I can not use the operator-function syntax to invoke a primitive operator, which happens to exist as part of the language.
Vatsan
@Vatsan: I don't think it exists unless you explicitly declare it, and you can't declare it for non-class types.
David Titarenco
@David - That makes sense. I was secretly hoping that there was some requirement in the standard that only the redefinition of primitive operators was prohibited, but the invocation syntax was treated the same for all of them, since it is merely syntactic sugar anyway and will have no appreciable impact on anything but readability. Thanks!
Vatsan
+1  A: 

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.

AndreyT
Exactly what I was looking for. Thanks!
Vatsan