1

I have a defined type Coordinates like so:

#include <array>
using Coordinates = std::array<double, 3>;

For which I call the following operator overload functions:

Coordinates operator+(const Coordinates& lhs, const Coordinates& rhs);
Coordinates operator*(const Coordinates& lhs, const Coordinates& rhs);

both overloads work, so that if I have 2 Coordinates variables :

C1 = { 1., 2., 3.} and C2 = { 1., 2., 3. }

C1+C2 returns { 2., 4., 6.}

C1*C2 returns { 1., 4., 9.}

Now I want to define a *+ operator such that:

C1*+C2 returns 1. + 4. + 9. or 14.

I tried the following implementation:

Coordinates operator*+(const Coordinates& lhs, const Coordinates& rhs)
{
    return lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2];
}

however, *+ is not a pre-defined operator. Then I tried this format:

Coordinates operator "" *+(const Coordinates& lhs, const Coordinates& rhs)
{
    return lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2];
}

but I get this : invalid literal operator name. Understandable how about this:

double operator "" _d_(const Coordinates& lhs, const Coordinates& rhs)
{
    return lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2];
} 

_d_ stands for dot as in dot product, but now I get this error too many parameters for this literal. Is it possible to define an operator for the dot product or do I have to write a dot() function?

Hadi Farah
  • 1,091
  • 2
  • 9
  • 27
  • 1
    User-defined literals are a way of creating new literal types. Just as it's not possible to make up your own operators, you can't have a literal with two values. – Some programmer dude Jan 30 '19 at 15:17
  • I would avoid to overload operators for foreign class only. future std might add legally `operator +` for array leading to possible break of ODR. – Jarod42 Jan 30 '19 at 15:32
  • Not sure - what do you need the *current* `operator*` for, in other words: which math would use the component-wise product? Wouldn't it be more meaningful to let `operator*` calculate the dot product (what your new operator would do) and just drop the component-wise one? – Aconcagua Jan 30 '19 at 15:37
  • The literal operator is intended for totally different things... – Aconcagua Jan 30 '19 at 15:40
  • @Aconcagua I need it for scaling, I am doing this for finite element purposes which involves a lot of local to global mapping and vice versa. I can just define `Scaling = Coordinates { a, b, c}` and scale all my vertices by doing Scaling * vertex, since my vertices would also be `Coordinates`. As for the literal operator I didn't know about it, until I read about 20 mins ago. I am trying to explore my options. I tried to go around it by overloading `++` to sum all the inner values but that only returns int and I cannot change it. If that worked I can do something like `(C1*C2)++` – Hadi Farah Jan 30 '19 at 15:42
  • @Aconcagua nevermind it does work. I now do `(C1*C2)++` get get my intended purpose. This is fine because I never need to increment coordinates by 1. over x,y,z. or any value for that matter – Hadi Farah Jan 30 '19 at 15:47

2 Answers2

3

You can only overload 38 existing operators for your type. Which are listed here: https://en.cppreference.com/w/cpp/language/operators

op - any of the following 38 (until C++20) 39 (since C++20) operators:
+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= <=>(since C++20) && || ++ -- , ->* -> ( ) [ ]

literal operators work on single argument and convert literals (like 42, "foobar") to objects. Since you already have objects, you have to use operator overloading. Pick any of the available ones.

Max Langhof
  • 23,383
  • 5
  • 39
  • 72
balki
  • 26,394
  • 30
  • 105
  • 151
  • I see, thank you. I was just asking because of my lack of experience and hoping somebody can give me a clear answer. – Hadi Farah Jan 30 '19 at 15:24
1

First off you can look at the list of operators to see what exists here to see which can and cannot be overloaded.

On the second point, you can probably try something like this answer to make a custom operator. Keep in mind this isn't technically a new operator (as you can't make your own in C++) but does involve a bit of template magic to accomplish the same thing.

Rietty
  • 1,116
  • 9
  • 24