Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to force the user of a C++ function to acknowledge the semantic meaning of parameters that are numerical constants?

Tags:

c++

I'd like to write function interfaces that force the user to acknowledge the semantic meaning of built-in constants. For example, I'd like to take

void rotate(float angle); // Rotate the world by an angle in radians.

and change it to

void rotate(Radians angle);

Am I right in believing that the problem with making a Radians class is that it adds code and makes the program slower. Is there a better way to do this?

like image 493
May Oakes Avatar asked Jan 25 '10 21:01

May Oakes


People also ask

What are the various methods of parameter passing to function in C?

There are two ways to pass parameters in C: Pass by Value, Pass by Reference.

How do you call a function in C programming?

Function Calling: It is only called by its name in the main() function of a program. We can pass the parameters to a function calling in the main() function. Syntax: Add(a, b) // a and b are the parameters.

Which of the following options can be used to call function in AC program?

Function call by value is the default way of calling a function in C programming.


1 Answers

No, it is possible to make a Radians class that should be optimized by most decent compilers into something that's no slower than a plain float. You might be interested in boost.units.

In fact, with boost.units you can even set it up so that if someone wants to pass in an angle in degrees it will automatically be converted to radians before being passed to the function. That will possibly slow things down a bit, but it arranges it so you can change what units a function wants without having to go back and edit a whole ton of code.

And, when you finally do want to go and edit all the code, you can temporarily fix it so the conversion doesn't work and let the compiler find it for you.

Being able to make the compiler enforce constraints like this for you with no runtime penalty and possibly even write all the conversion code for you (at a very tiny runtime penalty) is one of the really neat things about C++ and makes it worth the added complexity over C.

Here is a really simple version of what this class might look like if you hand coded it:

#include <cmath>

// This class is tiny enough because it has no virtual functions and only one
// data member that it's likely more efficient to pass by value than by
// reference.
class Radians {
 public:
   // If you don't put in explicit, the compiler will automatically convert a
   // float to a Radians for you and undo all of the hard work you did to make
   // sure callers express their intentions.
   explicit Radians(float radians) : value_(radians) {}

   float getValue() const { return value_; }
   void setValue(float radians)  { value_ = radians; }

   float asDegrees() const { return value_ * 180 / M_PI; }

   // This allows you to say Radians r = Radians::fromDegrees(something);
   static Radians fromDegrees(float degrees) {
      return Radians(degrees * M_PI / 180);
   }

 private:
   float value_;
};

Notice how all of the functions are declared in the class body. This makes them all implicitly have the inline keyword. A good compiler will optimize all of those functions out of existence. Of course, the conversion functions will generate the code to do the conversion, but otherwise it'll be the same as having a bare float.

like image 104
Omnifarious Avatar answered Oct 20 '22 18:10

Omnifarious