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.