"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:
...
# define
identifier replacement-list new-line
# define
identifier lparen identifier-listopt) replacement-list new-line
# define
identifier lparen ... ) replacement-list new-line
# define
identifier 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.