/* class v2 { double x, y; ... }; */
/* #1) */
v2 vtemp = v2( 5.0, -2.0 ) - v2( 3.0, -5.0 );
printf( "The resulting vector is <%.3f %.3f>", vtemp.x, vtemp.y );
/* #2) */
v2 vtemp = v2( 5.0, -2.0 ) - v2( 3.0, -5.0 );
printf( "The resulting vector is <%.3f %.3f>", vtemp );
/* #3) */
printf( "The resulting vector is <%.3f %.3f>", v2( 5.0, -2.0 ) - v2( 3.0, -5.0 ) );
/* (Each produces the same output) */
For the sake of temporary variables...
Consider:
Which would you prefer?
I prefer the first one, as the second and third relies on undefined behaviour. You cannot safely pass non-trivial types to functions using variable number of arguments if I remember correct.
Quote:Original post by Brother Bob
I prefer the first one, as the second and third relies on undefined behaviour. You cannot safely pass non-trivial types to functions using variable number of arguments if I remember correct.
But wouldn't the program write the contents of the class into the va_list anyways? Therefore, wouldn't it be safe to say "%f %f" expects two consecutive doubles, which is also a "v2"?
Not necessarily no. Some compilers/architectures treat structs/classes passed by value in wierd ways. I wouldn't be the least bit surprised if your code doesn't work on ia64 for example.
You are firmly in undefined territory here.
You are firmly in undefined territory here.
Since you're using C++ ideas like operator overloading, why not:
Or if you really dislike c++ streams, a better way to engineer your v2 might be to do:Of course you have to add a toString() method for v2... but then it's likely that being able to serialize a v2 object might be useful anyway.
v2 vtemp = v2( 5.0, -2.0 ) - v2( 3.0, -5.0 ); cout << "The resulting vector is " << vtemp );
Or if you really dislike c++ streams, a better way to engineer your v2 might be to do:
v2 vtemp = v2( 5.0, -2.0 ) - v2( 3.0, -5.0 ); printf("The resulting vector is %s", vtemp.toString());
Quote:Original post by Anon Mike
I wouldn't be the least bit surprised if your code doesn't work on ia64 for example.
Just tried it on x64 in VC8 and it actually didn't work.
If you were actually writing code in a sane way using type-safe library functions, the last would be what you want. In idiomatic C++:
Naming things implies that they're important enough to be named. If you're only going to write the expression once and use its value once, it is unlikely to be that important.
Of course, context is everything: normally you would want to subtract vectors that *already existed* for some reason, so those variables would already be there. But there would still be no reason to explicitly declare a variable to represent their difference.
cout << "The resulting vector is " << (v2( 5.0, -2.0 ) - v2( 3.0, -5.0 ));
Naming things implies that they're important enough to be named. If you're only going to write the expression once and use its value once, it is unlikely to be that important.
Of course, context is everything: normally you would want to subtract vectors that *already existed* for some reason, so those variables would already be there. But there would still be no reason to explicitly declare a variable to represent their difference.
(Not a big fan of cout; I find it unnecessarily elaborate.)
I want to get rid of the temporary variables if I can, so I don't have to declare "vtemp" everytime...
I guess toString() suits my needs the best...
I want to get rid of the temporary variables if I can, so I don't have to declare "vtemp" everytime...
I guess toString() suits my needs the best...
class v2 {public:/* ... */ std::string toString( const char *form = "<>", unsigned int perc = 3 ) {#ifdef _DEBUG assert( strlen( form ) > 1 );#endif /* std::string ztl::format( char *format, ... ); step 1: "%c%%.%uf %%.%uf%c" -> "<%.3f %.3f>" step 2: "<%.3f %.3f>" -> "<x y>" */ return ztl::format( ztl::format( "%c%%.%uf %%.%uf%c", form[0], perc, perc, form[1] ).c_str(), x, y ); }};
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement