Prev: Detecting pointer on the heap
Next: warning: dereferencing pointer does break strict-aliasing rules
From: Thiago A. on 31 Mar 2010 07:36 Using function notation we have expressions like that: F(G(H(X))) Where we have to read from inside to outside. It is not so bad; this is the normal mathematical notation. However in some cases, I would prefer to read expression from left to right applying the next function in the previous result. H(x) G() F() We can have this kind of expressions using member functions. x.H().G().H(); In this case, each return type must have member functions for that algorithm. But algorithms can me separated from data. The solution that I could think about is to have an overload for operator dot. ReturnType operator . H (const X& x) { } This operator dot would be valid only if the expression x.H() was not defined before using member functions. The syntax sugar would be useful in some cases. For instance, we could write: matrix.Rotate(pi).ReflectHor().Inverse(); instead of: Inverse(ReflectHor(Rotate(matrix))); Is this too much syntax sugar? Is the dot operator overload too hard to be defined? (I know that we can�t do this today) Also in C++ we don�t have this kind of syntax sugar: using x { .Rotate(pi); .RefelectHor(); .Inverse(); } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Seungbeom Kim on 31 Mar 2010 08:51 On 2010-03-31 15:36, Thiago A. wrote: > > However in some cases, I would prefer to read expression from left to > right applying the next function in the previous result. > > H(x) G() F() Only in the (special) case where each function takes one parameter. Expressions could be made readable from left to right in general, for example, with a notation that puts the function name on the right: (w, ((x, y)f1, z)f2)f3 instead of f3(w, f2(f1(x, y), z)) but this deviates too much from the conventional mathematical notation. Furthermore, if an expression becomes too long and complicated to parse at a glance, it's always a good idea to break it up into smaller expressions and give them proper names. > The syntax sugar would be useful in some cases. > > For instance, we could write: > > matrix.Rotate(pi).ReflectHor().Inverse(); > > instead of: > > Inverse(ReflectHor(Rotate(matrix))); This is already possible, for example, if matrix is an object of a class that has member functions Rotate, ReflectHor, and Inverse, and they all return the reference to *this. This is not much different from the operator chaining: std::cout << std::setw(8) << value << std::endl where each function returns the reference to the stream. > Also in C++ we don�t have this kind of syntax sugar: > using x { > .Rotate(pi); > .RefelectHor(); > .Inverse(); > } Because it can easily be written out: x.Rotate(pi); x.ReflectHor(); x.Inverse(); If x turns out to be a long expression you don't want to repeat, you can create an alias: T& x = long_expression_with(arguments); x.Rotate(pi); x.ReflectHor(); x.Inverse(); where T could be just written as "auto" in the next version of C++. -- Seungbeom Kim [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: pfultz2 on 31 Mar 2010 11:36 > For instance, we could write: > > matrix.Rotate(pi).ReflectHor().Inverse(); > > instead of: > > Inverse(ReflectHor(Rotate(matrix))); You don't need to overload the dot operator to get this kind of behaviour. You just have each function return another matrix or a reference to a matrix like so: class Matrix { public: Matrix& Rotate(double val) { //Do calculations return *this; } Matrix& ReflectHor() { //Do calculations return *this; } Matrix& Inverse() { //Do calculations return *this; } }; You could return a copy instead of reference if you have an immutable matrix class. But now you can use your class like so: Matrix m; m.Rotate(3.14).ReflectHor().Inverse(); -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Andy Venikov on 31 Mar 2010 11:36 Thiago A. wrote: > Using function notation we have expressions like that: > > F(G(H(X))) > > Where we have to read from inside to outside. It is not so bad; this > is the normal mathematical notation. > > However in some cases, I would prefer to read expression from left to > right applying the next function in the previous result. > > H(x) G() F() > > We can have this kind of expressions using member functions. > x.H().G().H(); > > In this case, each return type must have member functions for that > algorithm. But algorithms can me separated from data. > The solution that I could think about is to have an overload for > operator dot. > > ReturnType operator . H (const X& x) > { > } > > This operator dot would be valid only if the expression x.H() was not > defined before using member functions. > > The syntax sugar would be useful in some cases. > > For instance, we could write: > > matrix.Rotate(pi).ReflectHor().Inverse(); > > instead of: > > Inverse(ReflectHor(Rotate(matrix))); You can't overload operator . () But in your case you don't need to. Just have every algorithm function (like Rotate()) return a reference to a (non-local) object that defines other needed functions, like ReflectHor() HTH, Andy. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Thiago A. on 31 Mar 2010 12:04 > > However in some cases, I would prefer to read expression from left to > > right applying the next function in the previous result. > > > H(x) G() F() > > Only in the (special) case where each function takes one parameter. > > Expressions could be made readable from left to right in general, for > example, with a notation that puts the function name on the right: > > (w, ((x, y)f1, z)f2)f3 > > instead of > > f3(w, f2(f1(x, y), z)) > > but this deviates too much from the conventional mathematical notation. The first argument is always the one we can put before the dot, and we could have N arguments. For instance, using your sample: f3(w, f2(f1(x, y), z)) and changing names just to express the idea: f3_DotProduct(w_vector, f2_Normalize( f1_Rotate(x_vector, y_scalar), z_scalar)) could be written: vector_w.f3_DotProduct(vector_x.f1_Rotate(scalar_y).f2_Normalize(scalar_z)); -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Next
|
Last
Pages: 1 2 3 Prev: Detecting pointer on the heap Next: warning: dereferencing pointer does break strict-aliasing rules |