Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use an arbitrary character as an operator?

Tags:

c++

operators

As a prior note: This is not something I would 'desire' to achieve; more-so a question related to if it's actually possible.

N.B. I understand (and have used) Operator Overloding in C++. For example:

std::ostream& operator<<(std::ostream& os, const T& obj){ return os; }

Is it possible to define a custom ASCII character to act as an operator?

For example, in a simple sense: use the grave accent (`) as an 'alias' for std::pow.

Whereby, the following statement would be valid/achievable:

std::cout << 2`3 << std::endl;

>> 8
like image 709
Alfie J. Palmer Avatar asked Mar 04 '15 09:03

Alfie J. Palmer


2 Answers

You cannot introduce a character not present in the syntax, such as the backtick you mentioned. But there is a "named operator" trick with which you can introduce a "named operator" to achieve the following syntax:

std::cout << (2 <Pow> 3) << std::endl;

The trick relies on overloading < and > for a custom type, like this:

const struct PowOperator {} Pow;

struct PowInvoker
{
  int lhs;
};

PowInvoker operator< (int lhs, PowOperator)
{
  return {lhs};
}

int operator> (PowInvoker lhs, int rhs)
{
  return std::pow(lhs.lhs, rhs);
}

int main()
{
  std::cout << (2 <Pow> 3) << std::endl;
}

[Live example]

Notice that you cannot affect the precedence of these named operators: they will have the same precedence as <, <=, >, and >=. If you need different precedence, you'd have to use a different delimiter (which would probably not be as nicely readable).


Disclaimer

The above trick is "clever" code, it's pretty much an abuse of the C++ syntax. I took the question as a hypothetical "what is possible," and answered with an equally hypothetical "this is." I would not recommend using this in practice for such trivial matters as replacing std::pow or providing "novelty" syntax for the sake of it. The operator precedence caveat mentioned above is one reason; general unfamiliarity of the construct is another. Code quality is measured in the number of WTFs the code generates (fewer is better), and this trick generates a whole bunch of them (and big ones at that).

It still has its uses: for creating a Domain-Specific Language. There are cases in programming where embedding a DSL into C++ code is in order; in such cases (and only in such cases) would I consider using this.

like image 138
Angew is no longer proud of SO Avatar answered Nov 04 '22 23:11

Angew is no longer proud of SO


No, that is not possible. Even at the preprocessor level you are limited by the characters that form valid preprocessor tokens and macro names, and then the language grammar fixes the set of operators in the language.

like image 37
Kerrek SB Avatar answered Nov 04 '22 21:11

Kerrek SB