How do we change an operator character in c++

Anyone very knowledgeable in C++ so able to change an operator character ?
e.g.

a != b

become

a >< b


What the real wanted or asked is the constructor initialization e.g.

class I

int v;
public:
I(int n) : v(n) {}


become

I(int n) : v := n {}


nowadays some PLs able to get it such easily
Last edited on
Why? Changing an operator makes it non-standard.
Anyone very knowledgeable in C++ so able to change an operator character?
It's not possible. Your options include writing a code generator, using a better preprocessor, and extending your compiler.

The only built in candidate is the C preprocessor, a very primitive tool. The preprocessor is incapable of replacing <> or :=.

You asked a question about meta-programming before, so I'll just clarify that there are no syntax macros in C++, although syntax macros of moderate complexity can be emulated, badly, by abusing templates in certain contexts (not here). See "template meta-programming", a minefield for even experts. For "reader macros" there is the C preprocessor, which is terribly incapable.
Last edited on
you can use the keywords, and, not, or etc instead of symbols if you hate it that much.
If it was possible to define your own operators I think it would easily lead to ambiguous or error-prone syntax that would be hard for compilers and other tools to parse (and for humans too).

For example, should x<y><z> be treated as x<(y!=z)>) or should it be treated as ((x<y>) < z) > ... or as (x<y) != (z > ...)?

In many situations it might be possible to know from the context what it means. The compiler already has to know whether something is a type or not to be able to parse things properly in many situations, and in some situations the syntax is actually incompatible but the standard always specifies what it should mean.

Before C++11 you couldn't write std::vector<std::vector<int>> because >> was parsed as a right shift operator.

The function declaration syntax is incompatible with the () initialization syntax. E.g. std::string x(); Should this be treated as a definition of a std::string variable named x that is initialized using the default constructor, or should it be treated as a declaration of a function named x that takes no arguments and returns an int? The C++ standard specifies that it should be the latter.

When new syntax is added to the language they try to avoid these sort of ambiguities. If you accidentally misspell something it's also good if it gives a compilation error and not just happen to be interpreted as something completely different. They also don't want to make the life too hard for the implementers of compilers and other C++ tools.

If programmers would be able add new operators on their own I only see chaos and code that is incompatible with each other. You might define >< to mean != but I might define it to mean =. It would essentially create different "dialects" of C++ that are incompatible with each other and that is something that the C++ standards committee don't want. They also don't want to break existing code when adding new stuff but if the user can add their own operators it would be much more difficult to add new syntax to the language without breaking someone's code.

Note that the () initialization syntax for the constructor initialization list is not an operator so to get that := syntax to work in the constructor initialization list it would not be enough to just be able to define your own operators.
Last edited on
At the end of the day, an operator is just a (symbolically-convenient and familiar) alias for a function.

If you want >< then simply write, e.g.,
bool greaterThanOrLessThan( int a, int b ){ return a != b; }
(but don't expect anyone else to follow you!)
Last edited on
I could follow it: that would be perfectly readable, though I would define a greater than and a less than distinctly. Its a bit obnoxious, but it would be fine and readable.

I found the ! to be weird for a little while too. If your first language didn't do it that way, its an odd choice for 'not'. The rest are pretty much what you expect from math. == instead of = is a common aggravation for beginners as well. <> is iffy anyway. What you REALLY want to define here is ≠ but that symbol is not easy to type into your code text file, and back 75ish years ago when all this started it may not even have existed in ascii which is all they had, no unicode or extended ascii etc to pull from, they had 128 symbols and those were eaten up with special commands and upper/lower case ... its pretty tight with more than half just for letters and numbers...
I guess you could do =/= since 3 char operators are OK in c++, but that would be annoying... very, very annoying.
Last edited on
I guess you could do =/= since 3 char operators are OK in c++

Mistype =/= when using the operator and it might end up at /=, similar aggravation as mistyping = for ==.
=! can lead to similar problems.
Can I define my own operators?

Sorry, no. The possibility has been considered several times, but each time I/we decided that the likely problems outweighed the likely benefits.

It's not a language-technical problem. Even when I first considerd it in 1983, I knew how it could be implemented. However, my experience has been that when we go beyond the most trivial examples people seem to have subtlely different opinions of "the obvious" meaning of uses of an operator. A classical example is a**b**c. Assume that ** has been made to mean exponentiation. Now should a**b**c mean (a**b)**c or a**(b**c)? I thought the answer was obvious and my friends agreed - and then we found that we didn't agree on which resolution was the obvious one. My conjecture is that such problems would lead to subtle bugs.
https://www.stroustrup.com/bs_faq2.html#overload-operator
But don't you just need to define the operator's associativity; left - right or right - left and it's precedence?
That is the real problem; for the same operator there could be different rules of associativity and precedence defined by different programmers. In anything other than a toy program, it would create a holy mess.

As it is, even with standard operators where associativity and precedence are specified (indirectly) by the standard:

Preserve natural semantics for overloaded operators.

Programmers hate surprises: Overload operators only for good reason, and preserve natural semantics; if that's difficult, you might be misusing operator overloading.

Although anyone would agree (we hope) that one should not implement subtraction in an operator+ implementation, other cases can be subtle. For example, does your Tensor class's operator* mean the scalar product or the vector product? Does opera-tor+ =( Tensor& t, unsigned u ) add u to each of t's elements, or will it resize t? In such ambiguous or counterintuitive cases, prefer using named functions instead of fostering cryptic code.
...
Mimicking the behavior of and relationships among operators on built-in types ensures that you don't surprise anyone. If your semantics of choice are likely to raise eyebrows, maybe operator overloading is not a good idea.

- Alexandrescu and Sutter in 'C++ Coding Standards'
BTW, a**b**c should be a**(b**c), mathematically speaking. But a very many programming languages do it the wrong way around when offering the option.

...because programming languages != math.
...because programming languages <> math.
Last edited on
FWIW several programming languages allow definition (and overloading) of operators with arbitrary names - Haskell, or, for a more practical example, Scala. I found that enjoyable when working on those codebases... But yes, not going to happen in C++.
Last edited on
I would love to have this, even if its like goto and a high risk tool, it would be fun and occasionally useful, moreso if we can define the symbol from anything in unicode. Matching math books/papers/etc symbol for symbol ... has merits. Or opening up the variables so we can have greek symbols or whatnot...
Last edited on
Cubbi wrote:
several programming languages allow definition (and overloading) of operators with arbitrary names - Haskell

Haskell is not as as heavy on the syntax. I imagine it must be much easier to have this in a language if you plan for it from the start.

jonnin wrote:
if we can define the symbol from anything in unicode. Matching math books/papers/etc symbol for symbol ... has merits. Or opening up the variables so we can have greek symbols or whatnot...

You mean like https://godbolt.org/z/3qonahfWT ?

Personally I prefer if anyone can just type the identifiers with their keyboards without having to copy-paste.
Last edited on
What the real wanted or asked is the constructor initialization e.g.

Initialization is not "operator", is it?

We do already have two syntaxes for it in C++:
1
2
3
I(int n) : v(n) {}

I(int n) : v{n} {}



Lets say that you could redefine syntax. You would have to spend time to create your own syntax and anyone who needs to maintain your code (including your future self) has to spend time to figure out what is done in your code.

The C++ syntax is plenty to learn as is, and you want more to learn? In practice nobody will be able to read your code. Unmaintainable code is worthless.


Except, if you try to obfuscate your code. The persons that you don't want to read your code will figure out what you did.
BTW, a**b**c should be a**(b**c)

:) :) right associative.

but which way did Stroustrup want to assume for the default??

that one should not implement subtraction in an operator+ implementation


unless you're using Doublespeak...
Last edited on
Topic archived. No new replies allowed.