Bad code here

Published June 25, 2004
Advertisement
Despite the fact you can't actually create new operators in C++, it's possible to create new "psuedo-operators". Warning: bad code ahead.

Let's say you're a game developer working on your first 3D engine. One of the classes you're going to write is a vector class. It might look something like:
class Vector {  public:    Vector(float x = 0.0f, float y = 0.0f, float z = 0.0f)      : x_(x), y_(y), z_(z) {}    float x_;    float y_;    float z_;    // other stuff excluded};float dot_product(const Vector & lhs, const Vector & rhs) {  return ( (lhs.x_ * rhs.x_) +           (lhs.y_ * rhs.y_) +           (lhs.z_ * rhs.z_) );}Vector cross_product(const Vector & lhs, const Vector & rhs) {  return Vector( (lhs.y_ * rhs.z_ - lhs.z_ * rhs.y_),                 (lhs.z_ * rhs.x_ - lhs.x_ * rhs.z_),                 (lhs.x_ * rhs.y_ - lhs.y_ * rhs.x_) );}

You'd really like to overload operators for the dot and cross product, but everyone tells you it's a honking bad idea. operator * is ambiguous, you can't get at operator . and so on.

Now what if you could turn any identifier into an operator? Let's say the dot product could be represented by dot. So if you had two vectors you could do just a dot b. Of course this generates a syntax error, consecutive identifiers aren't a happy construct in C++. So the operator needs to be made to be something other than an identifier somehow. One method is to bracket it on either side by something. %dot% or or *dot* or ^dot^ or something. Let's go with for the moment since in C++, <> brackets are often used for magic things (like templates and new style casts).

Now, what happens when the parser runs across a b? It turns it into ((a < dot) > b). So if we make dot an object of some sort, we can abuse operator overloading, and the associativity of relational operators to get this to actually compile and do what we want. And since we're already off the deep in terms of good coding practices, might as well throw in a preprocessor macro to automate the whole thing.

template <typename T, typename Op>struct LtProxy {  LtProxy(T r) : ref_(r) {}  T ref_;};#define MAKE_OPERATOR(name, lhs_type, rhs_type, result_type, worker_function) \   const struct name ## _t {} name;                                            \   LtProxy operator <(lhs_type lhs, name ## _t rhs) {    \     return LtProxy(lhs);                                \   }                                                                           \   result_type operator>(LtProxy & lhs, rhs_type rhs) {  \     return worker_function(lhs.ref_, rhs);                                    \   }MAKE_OPERATOR(dot,   const Vector &, const Vector &, float,  dot_product);MAKE_OPERATOR(cross, const Vector &, const Vector &, Vector, cross_product);int main(int, char **) {  Vector a(0, 1, 3);  Vector b(4, 2, 1);   float dot_product = a  b;   std::cout << dot_product << std::endl;    Vector cross_product = a  b;  std::cout << cross_product.x_ << std::endl;  std::cout << cross_product.y_ << std::endl;  std::cout << cross_product.z_ << std::endl;    return 0;}

It's horribly abusive, not too maintainable, and can give operator precedence headaches, but I think it's kind of fun.

I'm tempted to put it into my new unified code library somewhere, but it violates just about every coding standard I've set for the the project. Oh well. It's immortalized here if I ever want to get at it again. :)
Previous Entry Yay?
Next Entry Ignore this entry
0 likes 3 comments

Comments

Kylotan
That's possibly the best and worst C++ code I've ever seen. :)
June 26, 2004 06:41 AM
23yrold3yrold
oh teh noes teh C++ macros ... evil. [wink]

*cough*comment leaving test*cough*
June 26, 2004 11:38 AM
SiCrane
Well, I warned you guys. :) Bad code ahead and all that.
June 26, 2004 04:28 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement

Latest Entries

New bug to me

1680 views

Week/Class 9

1519 views

Week/Class 8

1557 views

Week/Class 7

1607 views

The promised files

1836 views

Week/Class 6

1302 views

Week/Session 5

1357 views

Week/Session 4

1297 views

On the soapbox

1398 views

Week/Session 3

1274 views
Advertisement