Videos
How are file operators in C used?
How many types of operators are there in C language?
Can you overload operators in C?
"Now, is there any way to define it instead that with an operator, with some function?"
No, !+ doesn't form a valid (normal) identifier for a preprocessor macro. The characters are reserved for language intrinsic operators.
The set of characters you can use for macro definitions is [_A-Za-z][_A-Za-z0-9]*regex syntax1.
As from the c++ standards definitionsdraft section
16 Preprocessing directives
...
control-line:
...
# defineidentifier replacement-list new-line
# defineidentifier lparen identifier-listopt) replacement-list new-line
# defineidentifier lparen ... ) replacement-list new-line
# defineidentifier lparen identifier-list, ... ) replacement-list new-line
UPDATE:
I've been experimenting with this a bit, since this actually is an interesting question, and if not #define'd macros, we can use overloading intrinsic operator functions for classes in c++.
I have found there actually are possible (but may be weird and unexpectedly behaving) options, to overload combinations of intrinsic operators by chaining them and keep state. The closest thing you can get for your newly introduced operator could be:
class Foo {
enum OpState { None , PlusState , NotState };
public:
Foo& operator+() {
cout << "operator+()" << endl;
opState = PlusState;
return *this;
}
Foo& operator!() {
cout << "operator!()" << endl;
switch(opState) {
case PlusState:
operatorexclamativeplus();
break;
default:
opState = NotState;
break;
}
return *this;
}
private:
Foo& operatorexclamativeplus() {
cout << "operatorexclamativeplus()" << endl;
opState = None;
return *this;
}
Foo& operatorexclamativeplus(const Foo& rhs) {
cout << "operatorexclamativeplus(const Foo& rhs)" << endl;
opState = None;
return *this;
}
OpState opState;
};
int main() {
Foo x;
Foo z = !+x;
return 0;
}
Output
operator+()
operator!()
operatorexclamativeplus()
See live sample.
Though, because of operator precedence rules, this would work only for unary operators (! has higher precedence than binary +), the form you want to have doesn't seem to be actually achievable:
class Foo {
// ...
public:
// Provide an additional binary 'operator+()'
friend Foo& operator+(Foo& lhs, const Foo& rhs) {
cout << "operator+(Foo& lhs, const Foo& rhs)" << endl;
if(lhs.opState == NotState) {
return lhs.operatorexclamativeplus(rhs);
}
return lhs;
}
// ...
};
int main() {
Foo x;
Foo y;
Foo z = y !+ x;
return 0;
}
See this miserably fail.
CONCLUSION:
- Some overloaded combinations of intrinsic operators might be syntactically possible, regarding their precedence definitions, and maintaining state of lvalues.
- It's probably not a very good idea, to try to overload intrinsic operator behavior, introducing completely new semantics.
______________________________________________________________________________________
1)
Regarding leading underscores (_,__) for identifiers please read the standards sections mentioned in this answer, these are syntactically valid though.
Technically, C++ does not let you define new operators. However, you can get any behavior you want out of existing operators, including the appearance of having a new operator.
(Not saying it's a good idea, just answering the question "Is it possible?")
You can not ever write a !+ b, becuase ! is not a binary operator.
But you can write a +! b because + is binary and ! is unary.
And you can redefine those operators so that a +! b returns what you want.
The trick is that you define the unary operator to return a helper object, and then define the binary operator to act upon that helper object.
As an example, here is code that will create the appearance of a +! operator. This new +! operator returns ten times the left hand side plus the right hand side. So... 1 +! 2 would yield 12.
class MyClass
{
public:
int value;
};
class MyClassHelper
{
public:
int value;
};
// define a unary ! operator that takes a right hand MyClass object
const MyClassHelper operator!(const MyClass right)
{
// this operator just copies the value into a MyClassHelper object
MyClassHelper answer;
answer.value = right.value;
return answer;
}
// define a binary + operator that takes a left hand MyClass object and a right hand MyClassHelper object
const MyClass operator+(const MyClass left, const MyClassHelper right)
{
// this operator should return the value you want the +! operator to return
MyClass answer;
answer.value = left.value * 10 + right.value;
return answer;
}
int main()
{
// initialize a and b
MyClass a, b;
a.value = 1;
b.value = 2;
// this line will now compile with the +! operator
MyClass c;
c = a +! b;
cout << "c = " << c.value << endl;
return 0;
}