0

I am trying to spend my free time with something useful. I am writing some codes based on linear algebra, defining Rn vectors, matrices and operations.

When I was writing the code for computing cross product between two R3 vectors, I faced a possibility of creating a new operator called x, then I could use u x v instead of u.vectorial(v);.

I'm telling you this because I read somethings and saw that with preprocessors I could do something like what I want. So, is there a way so I could do this?

ddz
  • 526
  • 3
  • 15
  • 3
    Whether you can doesn't matter. What matters is whether you *should*. Should you? No. – Kerrek SB Apr 04 '14 at 18:10
  • Knew I'd gotten the idea somewhere. Well, looks like it's already described here: http://stackoverflow.com/questions/15632217/defining-new-infix-operators – Ben Voigt Apr 04 '14 at 18:32
  • w = vector_product(u, v) - nice, simple and readable (avoid horseplay) –  Apr 04 '14 at 19:02

2 Answers2

7

This is not going to end well. C++ itself provides no support for creating new operators, only providing custom per-type behavior for the existing ones. And the preprocessor does nothing per-type, nor has any support for infix notation.

I sure wouldn't try to use single-letter operators, since they'll get replaced everywhere in your program.

To make something like u cross v work, you could

#define cross * cross_product_helper() *

And then use some techniques from expression trees -- the operator*(vec, cross_product_helper) returns a helper type that holds the vector and knows it wants to do cross product, the second use of * actually does the multiply.

On the other hand, would it be so bad to have the code written like:

u *cross* v

Where cross is a pre-defined, properly scoped variable of type cross_product_helper? (And of course you could have similar dot and element defined with unique types to make u *cross* v, u *dot* v, and u *element* v (and u /element/ v) all work and return different types.

Note that I've chosen operator* as the foundation for *cross*, as opposed to +cross+ or ^cross^, because it has the precedence and other grammatical properties associated with products.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • +1 for something I never would have thought of, though at this point I personally think `cross(u, v)`, `dot(u, v)`, etc. is clearer, cleaner, and easier to debug than this magic. – Cornstalks Apr 04 '14 at 18:16
  • 2
    @Cornstalks: But `dot(cross(u, v) * 2, element_product(element_product(x, y), z))` is not cleaner than `2 * (u *cross* v) *dot* (x *element* y *element* z)` – Ben Voigt Apr 04 '14 at 18:18
  • Touché, you win again. – Cornstalks Apr 04 '14 at 18:19
  • 2
    And it isn't hard for `dot` to both support `dot(x,y)` and `x *dot* y`. – Yakk - Adam Nevraumont Apr 04 '14 at 18:19
  • @Yakk: Very good point. Just give `dot_product_helper` an `operator()(vec, vec)`. – Ben Voigt Apr 04 '14 at 18:20
  • 1
    Nifty solution. Just to expand this, if you continue the lazy combine into some sort of expression statement, and don't reduce back to matrix until you have to (aka `other_expression operator*(cross_product_helper,matrix)` it is theoretically possible to reduce the total number of calculations and speed up the code by reducing to a triple cross product or higher. Cool. – IdeaHat Apr 04 '14 at 18:26
  • Was on Class, but i'll look into this and i think i'll gonna need some explanation too. :v – ddz Apr 04 '14 at 21:41
0

Do not use preprocessors. They are bad. Best to avoid. You should look into overloading operators. http://www.functionx.com/cpp/Lesson25.htm

Ed Heal
  • 59,252
  • 17
  • 87
  • 127