How to handle units in c++ interface - c++

I am currently designing an API where I want that the user to be able to write code like this:
PowerMeter.forceVoltage(1 mV);
PowerMeter.settlingTime(1 ms);
Currently we do this using defines like:
#define mV *1.0e-03
This makes it very convenient for the user to write their code and it is also very readable, but of course has also drawbacks:
int ms;
Will throw some compiler errors which are hard to understand. So I am looking for a better solution.
I tried the new C++11 literals, but with this all I could achieve is:
long double operator "" _mV(long double value) {
return value * 1e-3;
}
PowerMeter.forceVoltage(1_mV);
In the end the API does not care about the unit like Volt or second but only takes the number, so I don't want to do any checking if you really input Volts in forceVoltage or not. So this should also be possible:
PowerMeter.forceVoltage(2 ms);
Any idea besides staying with the defines?

how about instead turning it around a bit by creating classes (ms,mV) for the different currents
e.g.
PowerMeter.forceVoltage( mV(1) );
PowerMeter.settlingTime( ms(1) )
It is pretty clear to the user and arguably not hard to read plus you would get type checking for free. having a common base class for the different units would make it easier to implement.

You can see the library "C++ Units" from Calum Grant as a good example of how to implement this. The library is a bit outdated, but still worth to see or may be to use.
Also, i think it might be interesting to read: "Applied Template Metaprogramming in
SI UNITS: the Library of Unit-Based Computation"
There is one more good library: UDUNITS-2 which:
contains a C library for units of physical quantities and a unit-definition and value-conversion utility.

You could use C++11's compile-time rational arithmetic support for the units, instead of defining literals or macros for the units.

Take a look at Boost.Units.
Here's some example code:
quantity<energy>
work(const quantity<force>& F, const quantity<length>& dx)
{
return F * dx; // Defines the relation: work = force * distance.
}
...
/// Test calculation of work.
quantity<force> F(2.0 * newton); // Define a quantity of force.
quantity<length> dx(2.0 * meter); // and a distance,
quantity<energy> E(work(F,dx)); // and calculate the work done.

I prefer avoiding macros where ever I can, and this is an example where it should be possible.
One lightweight solution that gives you correct dimensions would be:
static double m = 1;
static double cm = 0.1;
static double mV = 0.001;
double distance = 10*m + 10*cm;
This also reflects the physical concept that units are something that's multiplied with the value.

Here's what I came up with... pretty much the same idea as Anders K, but since I wrote the code, I'll post it:
#include <iostream>
using namespace std;
class MilliVoltsValue;
class VoltsValue;
class VoltsValue
{
public:
explicit VoltsValue(float v = 0.0f) : _volts(v) {/* empty */}
VoltsValue(const MilliVoltsValue & mV);
operator float() const {return _volts;}
private:
float _volts;
};
class MilliVoltsValue
{
public:
explicit MilliVoltsValue(float mV = 0.0f) : _milliVolts(mV) {/* empty */}
MilliVoltsValue(const VoltsValue & v) : _milliVolts(v*1000.0f) {/* empty */}
operator float() const {return _milliVolts;}
private:
float _milliVolts;
};
VoltsValue :: VoltsValue(const MilliVoltsValue & mV) : _volts(mV/1000.0f) {/* empty */}
class PowerMeter
{
public:
PowerMeter() {/* empty */}
void forceVoltage(const VoltsValue & v) {_voltsValue = v;}
VoltsValue getVoltage() const {return _voltsValue;}
private:
VoltsValue _voltsValue;
};
int main(int argc, char ** argv)
{
PowerMeter meter;
meter.forceVoltage(VoltsValue(5.0f));
cout << "Current PowerMeter voltage is " << meter.getVoltage() << " volts!" << endl;
meter.forceVoltage(MilliVoltsValue(2500.0f));
cout << "Now PowerMeter voltage is " << meter.getVoltage() << " volts!" << endl;
// The line below will give a compile error, because units aren't specified
meter.forceVoltage(3.0f); // error!
return 0;
}

Consider using an enum for your units and pass it as a second parameter:
namespace Units
{
enum Voltage
{
millivolts = -3,
volts = 0,
kilovolts = 3
};
enum Time
{
microseconds = -6,
milliseconds = -3,
seconds = 0
};
}
class PowerMeter
{
public:
void forceVoltage(float baseValue, Units::Voltage unit)
{
float value = baseValue * std::pow(10, unit);
std::cout << "Voltage forced to " << value << " Volts\n";
}
void settlingTime(float baseValue, Units::Time unit)
{
float value = baseValue * std::pow(10, unit);
std::cout << "Settling time set to " << value << " seconds\n";
}
}
int main()
{
using namespace Units;
PowerMeter meter;
meter.settlingTime(1.2, seconds);
meter.forceVoltage(666, kilovolts);
meter.forceVoltage(3.4, milliseconds); // Compiler Error
}
Wrapping the Units namespace around the enums avoids polluting the global namespace with the unit names. Using enums in this way also enforces at compile time that the proper physical unit is passed to the member functions.

I prefer the solution from Anders K, however you may use a template to save some time implementing all units as a separte class which can be timeconsuming and prone to errors as you may need to write a lot of code by hand:
enum Unit {
MILI_VOLT = -3,
VOLT = 0,
KILO_VOLT = 3
};
class PowerMeter
{
public:
template<int N>
void ForceVoltage(double val)
{
std::cout << val * pow(10.0, N) << endl;
};
};
Use like this:
PowerMeter pm;
pm.ForceVoltage<MILI_VOLT>(1);
pm.ForceVoltage<VOLT>(1);
pm.ForceVoltage<KILO_VOLT>(1);

Before you go crazy with anything more complicated, whenever you write new code that takes a quantity as an argument you should name your methods like this so that it's 100% clear:
PowerMeter.forceInMilliVolts( ... )
PowerMeter.settlingTimeInSeconds( ... )
And similarly use variables with the right names e.g.:
int seconds(10);
int milliVolts(100);
This way it does not matter if you have to convert, it is still clear what you are doing e.g.
PowerMeter.settlingTimeInSeconds( minutes*60 );
When you are ready with something more powerful move to that, if you really need to, but make sure you do not lose the clarity of which unit is being used.

Related

Compile-time constructor switch in C++

Is there some sort of compile-time switch statement that I can use to pass parameters to a constructor for a member variable? Right now, I have a controller (in the control systems sense, not the MVC sense) that I need to be able to configure its operating frequency at compile time and a filter whose parameters depend on the selected frequency. Here is a skeleton of how I've implemented it:
#include <cstdint>
class Filter {
public:
Filter(float p1, float p2) : p1(p1), p2{p2} {}
private:
float const p1;
float const p2;
};
class Controller {
public:
Controller(void) {}
private:
static constexpr uint32_t frequency = 200U;
Filter filter{frequency == 400U ? 3.0f : // p1
frequency == 200U ? 1.0f :
frequency == 50U ? 0.55f : 0f,
frequency == 400U ? 2.0f : // p2
frequency == 200U ? 9.0f :
frequency == 50U ? 37.1f : 0f,
};
static_assert(frequency == 400U || frequency == 200U || frequency == 50U, "Invalid frequency");
};
This is obviously very difficult to maintain for large numbers of frequencies, even for only two filter parameters (the real software has more). Every time I need to add support for a new frequency, I need to add code to n points in the code, where n is the number of parameters for the filter. What I would like is something like this:
Filter filter = frequency == 400U ? {3.0f, 2.0f} :
frequency == 200U ? {1.0f, 9.0f} :
frequency == 50U ? {0.55f, 37.1f} :
{0.0f, 0.0f};
Or, in my wilder dreams:
Filter filter = static_switch_map(frequency) {
400U: {3.0f, 2.0f},
200U: {1.0f, 9.0f},
50U: {0.55f, 37.1f},
};
The parameters for the filter are not formulaically determined and thus cannot be written as part of an expression. Some additional notes:
I am using c++14 extensions in clang and GNU C++.
I am open to using a higher c++ extension and compiler extensions specific to GNU C++, though c++14 in both clang and GNU C++ preferred. clang-only solutions are no good to me.
This is for use in an embedded environment; a run-time solution using switch plus new plus pointers is unacceptable because of the indirection performance hit, binary file bloat, and the un-safeness of memory allocation in the embedded environment.
The Filter class may be instantiated multiple times.
Solutions involving templates are okay; I'm only using floats right now because I'm porting someone's Matlab code, but I will eventually switch to fixed-point math.
Other solutions I have considered include:
Conditional compilation using macros and define (the frequency variable I'm using in the real code is a custom data type, so I'd need to use define and a C++ variable that have similar roles; I don't like the idea of having frequency defined in two locations -- that's going to lead to maintenance problems down the road).
Rewriting variables using a custom preprocessor during the build process. Too magical and will likely become a gotcha to someone in the future.
Enums. I haven't ruled these out, but I can't think of how to use them in a way that would improve the code without the abilities of Java enums and/or a Python-like *args expansion. Admittedly, I've only been writing C++ for about four months (non-consecutively) and only had a solid year of experience with C before that, so there's a good chance I'm missing something, syntax-wise.
Separate include file to contain the magic; in my project, all automatically generated files have a separate extension, so this works. However, I prefer to have simpler build scripts and keep as much of the logic in the C++ code as possible.
Put your switch in a factory method and make your constructor private, so that you are forced to use that method.
This way you'll have only one point to update in your code in future:
struct Filter {
static Filter create(int freq) {
switch(freq) {
case 0: return { 0, 1 };
case 2: return { 3, 7 };
default: return { 0, 0 };
}
}
private:
Filter(int, int) {}
};
int main() {
auto filter = Filter::create(2);
(void)filter;
}
If you want to use it also at compile-time, you can slightly change it as it follows (this requires C++14):
class Filter {
constexpr Filter(int i, int j)
: i{i}, j{j}
{}
public:
static constexpr Filter create(int freq) {
switch(freq) {
case 0: return { 0, 1 };
case 2: return { 3, 7 };
default: return { 0, 0 };
}
}
constexpr int get_i() const { return i; }
constexpr int get_j() const { return j; }
private:
int i;
int j;
};
int main() {
constexpr auto filter = Filter::create(2);
static_assert(filter.get_i() == 3, "!");
}
Of course, you can easily add a copy constructor or whatever to your Filter class. This is a minimal example to show how the pattern works, nothing more.
Another way to define them separately and use each constructor through a call to a factory method is based on delegating constructors:
template<int>
struct freq_tag {};
class Filter {
constexpr Filter(int i, int j)
: i{i}, j{j}
{}
constexpr Filter(freq_tag<0>): Filter{0, 1} {}
constexpr Filter(freq_tag<2>): Filter{3, 7} {}
template<int N>
constexpr Filter(freq_tag<N>): Filter{0, 0} {}
public:
template<int N>
constexpr static Filter create() {
return Filter{freq_tag<N>{}};
}
constexpr int get_i() const { return i; }
constexpr int get_j() const { return j; }
private:
int i;
int j;
};
int main() {
constexpr auto filter = Filter::create<2>();
static_assert(filter.get_i() == 3, "!");
}
It's mainly a matter of taste if compared to the switch-based solution, but for the fact that this one should work also in C++11.

What is the difference between using the friend keyword, and using a member function to modify private variables inside of a class?

As the question asks...
What is the difference between:
class MyClass
{
public:
MyClass(){
m_a = 0;
}
private:
int m_a;
friend void set_a(MyClass &a);
};
void set_a(MyClass &a)
{
std::cout << a.m_a << std::endl;
a.m_a = 500;
std::cout << a.m_a << std::endl;
}
int main(void) {
MyClass my_class_instance;
set_a(my_class_instance);
system("pause");
}
and:
class MyClass
{
public:
MyClass(){
m_a = 0;
}
void set_a(){
std::cout << this->m_a << std::endl;
this->m_a = 500;
std::cout << this->m_a << std::endl;
}
private:
int m_a;
};
int main(void) {
MyClass my_class_instance;
my_class_instance.set_a();
system("pause");
}
Is it simply the preferred structure of the function, or are there real, measurable differences? From what I can tell, both functions achieve the same results in all circumstances, except if you had multiple overloads for the first example, that took different types of objects.
As the C++ FAQ says: Use a member when you can, and a friend when you have to.
There are situations where making friend a free function is preferable, most situations related to the fact that the first parameter of a member function is always of that class (Its the hidden *this parameter).
One example is arithmetic operators overloading:
Suppose you write a complex class which represents complex numbers. Using a member operator+() you could write expressions like complex + float, but not float + complex. But you could do it with the free form of the operator+:
class complex
{
...
friend complex operator+( float f , complex c );
};
This whole question comes down to "Why would I use friends in C++?". The answer is that when used properly, friends enhance encapsulation. This is an FAQ:
Do friends violate encapsulation?
Your example is too short and too abstract, of course. Some better, real life examples I could think of from the top of my head involve iterators. You may have many iterator objects referring to only one container object, and you may want the iterator to be able to access private member variables of the container. At the same time, you don't want the container to expose those variables to the rest of the world.
Such a design could be perfectly implemented with the friend feature.
Many people defend that making accessor methods, you can in a later stage of development put barriers to the incorrect access to the member variables (or even change the member variables totally) without breaking your (correct) clients.
One classical case is of a
class ComplexNumber {
double real, imaginary;
public:
double re() { return re; }
double setRe(double v) { return re = v; }
// and so on ...
};
one day you discover, in some maintenance, that you need the polar coordinates for that number, so you add the methods
double rho() { /* calculate rho */ }
double theta() { /* calculate theta */ }
double setRho(double v) { /* calculate real, imaginary, based on the new rho */ }
and so on.
Later yet, you discover that the users of the class use far more often polar than Cartesian coordinates for complex numbers, and that the conversions have been the bottleneck of a performance problem, so you ditch real and imaginary and store rho and theta, and change the getter and setter methods for the new -- more efficient -- storage for rho, theta, re, im, and so on. All the clients of your class will recompile without problems, because you changed your implementation but kept your interfaces stable.

Sum of particular members of an object array

This is my first question here, so hopefully it's a good one (I have searched for an answer, but not found it yet).
I have an event based disease model written in C++, and I'm trying to convert it to OOP (partly for my own learning experience). The basic class (Herd) stores numbers of susceptible, infective, and resistant animals, and the rates at which possible events occur.
class Herd {
private:
int S,I,R,N;
float birth, death, infection, recovery, movement;
public:
void calc_birth(void) { birth = r*N*(1.0-N/c); }
void calc_infection(void) { infection = N>0 ? beta*S*I/N : 0.0; }
// etc.
};
I then have a vector of herds to keep track of. Throughout this model I will need to calculate the sum of each member across all herd, after an event changes the number or category of individuals in a herd (this happens a lot). I already have 4 categories and 5 events, and this model could easily be expanded and require considerably more.
In my old, procedural code, I simply had a separate vector for each member, and it was easy to create a sum() function to calculate the results, but I can't see how to do this with a class without writing a separate sum function for each member (which is possible, but I doubt it's a particularly good way of doing it). I could make a static member (e.g. sum_S) to track the total, and update it every time an event occurs but this might not be appropriate for all members, and I'm not sure if the total might not slowly wander away from the true value when it comes to the rates.
Is there a way to write a single sum() function, which takes the member I want as a parameter, and returns the sum of that particular member across all the herds?
Thank you!
The standard library header numeric contains the function accumulate. It does not do exactly what you want, but is easily adaptable:
#include <numeric>
#include <vector>
#include <iostream>
struct Foo {
int member;
};
int main()
{
std::vector<Foo> v = { {1}, {2}, {3} };
int sum
= std::accumulate(begin(v), end(v), 0,
// lambda that sums up
[](const int& x, const Foo& y)
{return x + y.member;});
std::cout << sum << std::endl;
return 0;
}
The code uses initializer_lists and lambdas. If those aren't supported by your compiler, use the corresponding C++03 code (push_back and functors).
Sure, using pointer-to-members.
float sum_for_member( std::vector< Herd > const &herds, float Herd::*member ) {
float acc = 0;
for ( std:vector< Herd >::const_iterator it = herds.begin();
it != herds.end(); ++ it ) {
acc += (*it).*member;
}
return acc;
}
to call it:
float total_recovery = sum_for_member( my_herds, & Herd::recovery );
If you want to use a member function getRecovery instead, the parameter declaration becomes float (Herd::*member)() and the summation becomes acc += ((*it).*member)().
If you're not afraid to get further from OO and into generic C++ style, you can use a function template and let the Standard Library take care of the loop:
template< float Herd::*member >
float plus( float lhs, Herd const &rhs )
{ return lhs + rhs.*member; }
vector< Herd > h;
std::accumulate( h.begin(), h.end(), 0., plus< & Herd::recovery > );
So this is what I ended up with (inside a class called State, which holds the simulation state including a vector<Herd>):
Class State {
...
template <typename T>
T sum(T (Herd::*getter)()) {
T acc = (T) 0.0;
for (int i=0; i<size; ++i) {
acc += (herds[i].*getter)();
}
return acc;
...
}
This works for both the numbers of individuals (ints) and the event rates (floats), and uses pointers to member functions to keep those values private. An example of how this is called in the code is:
cout << "total # of S = " << state.sum(&Herd::getS)
"total # of I = " << state.sum(&Herd::getI)
"total birth rate = " << state.sum(&Herd::get_birth)
"total infection rate = " << state.sum(&Herd::get_infection)
etc.
Thanks very much for your help, especially to Potatoswatter. This is much better than the tedious boilerplate code I had before!

How to switch between 2 function sets in C++?

Is there a way, I can switch between 2 similar function sets (C/C++) in an effective way?
To explain better what I mean, lets say I have 2 sets of global functions like:
void a_someCoolFunction();
void a_anotherCoolFunction(int withParameters);
…
void b_someCoolFunction();
void b_anotherCoolFunction(int withParameters);
…
And I want to able to "switch" in my program at runtime which one is used. BUT: I dont want to have one if condition at every function, like:
void inline someCoolFunction(){
if(someState = A_STATE){
a_someCoolFunction();
}else{
b_someCoolFunction();
}
}
Because, I expect that every function is called a lot in my mainloop - so It would be preferable if I could do something like this (at start of my mainloop or when someState is changed):
if(someState = A_STATE){
useFunctionsOfType = a;
}else{
useFunctionsOfType = b;
}
and then simply call
useFunctionsOfType _someCoolFunction();
I hope its understandable what I mean… My Background: Im writing an App, that should be able to handle OpenGL ES 1.1 and OpenGL ES 2.0 both properly - but I dont want to write every render Method 2 times (like: renderOpenGL1() and renderOpenGL2() I would rather to write only render()). I already have similiar Methods like: glLoadIdentity(); myLoadIdentity(); … But need a way to switch between these two somehow.
Is there any way to accomplish this in an efficent way?
Several options, including (but not limited to):
Use function pointers.
Wrap them in classes, and use polymorphism.
Have two separate copies of the loop.
But please profile to ensure this is actually a problem, before you make any large changes to your code.
As the question seems to be interested in a C++ solution and no-one has spelt out the polymorphic solution (too obvious?), here goes.
Define an abstract base class with the API you require, and then implement a derived class for each supported implementation:
class OpenGLAbstract
{
public:
virtual ~OpenGLAbstract() {}
virtual void loadIdentity() = 0;
virtual void someFunction() = 0;
};
class OpenGLEs11 : public OpenGLAbstract
{
public:
virtual void loadIdentity()
{
// Call 1.1 API
}
virtual void someFunction()
{
// Call 1.1 API
}
};
class OpenGLEs20 : public OpenGLAbstract
{
public:
virtual void loadIdentity()
{
// Call 2.0 API
}
virtual void someFunction()
{
// Call 2.0 API
}
};
int main()
{
// Select the API to use:
bool want11 = true;
OpenGLAbstract* gl = 0;
if (want11)
gl = new OpenGLEs11;
else
gl = new OpenGLEs20;
// In the main loop.
gl->loadIdentity();
delete gl;
}
Note that this is exactly the sort of thing that C++ was intended for, so if can use C++ here, this is the simplest way to go.
Now a more subtle issue you might face is if your 2.0 version requires the process to load a dynamic linked library at run time with the 2.0 platform implementation. In that case just supporting the API switch is not enough (whatever the solution). Instead put each OpenGL concrete class in its own linked library and in each provide a factory function to create that class:
OpenGlAbstract* create();
Then load the desired library at run time and call the create() method to access the API.
In C (since it seems you want both C and C++) this is done with pointer to functions.
// Globals. Default to the a_ functions
void(*theCoolFunction)() = a_someCoolFunction;
void(*theOtherCoolFunction)(int) = a_anotherCoolFunction;
// In the code ...
{
...
// use the other functions
theCoolFunction = b_someCoolFunction;
theOtherCoolFunction = b_anotherCoolFunction;
...
}
You might probably want to switch those functions in groups, so you better set a array of pointers to functions and pass that array around. If you decide to do so, you might probably want to also define some macro to ease the reading:
void (*functions_a[2])();
void (*functions_b[2])();
void (**functions)() = functions_a;
....
#define theCoolFunction() functions[0]()
#define theOtherCoolFunction(x) functions[1](x)
....
// switch grooup:
functions = functions_b;
but in this case you'll lose the static check on argument types (and you have to initialize the array, of course).
I guess in C++ you will have instatiate two different objects with the same parent class and different implementation for their methods (but I'm no C++ prograammer!)
You could use functions pointers. You can read a lot about them if you google it, but briefly a function pointer stores a pointer to a function's memory address.
Function pointers can be used the same way as a funcion, but can be assigned the address of different functions, making it a somehow "dynamic" function. As an example:
typedef int (*func_t)(int);
int divide(int x) {
return x / 2;
}
int multiply(int x) {
return x * 2;
}
int main() {
func_t f = ÷
f(2); //returns 1
f = &multiply;
f(2); //returns 4
}
Something like boost::function (std::function) would fit the bill. Using your example:
#include <iostream>
#include <boost/function.hpp> //requires boost installation
#include <functional> //c++0x header
void a_coolFunction() {
std::cout << "Calling a_coolFunction()" << std::endl;
}
void a_coolFunction(int param) {
std::cout << "Calling a_coolFunction(" << param << ")" << std::endl;
}
void b_coolFunction() {
std::cout << "Calling b_coolFunction()" << std::endl;
}
void b_coolFunction(int param) {
std::cout << "Calling b_coolFunction(" << param << ")" << std::endl;
}
float mul_ints(int x, int y) {return ((float)x)*y;}
int main() {
std::function<void()> f1; //included in c++0x
boost::function<void(int)> f2; //boost, works with current c++
boost::function<float(int,int)> f3;
//casts are necessary to resolve overloaded functions
//otherwise you don't need them
f1 = static_cast<void(*)()>(a_coolFunction);
f2 = static_cast<void(*)(int)>(a_coolFunction);
f1();
f2(5);
//switching
f1 = static_cast<void(*)()>(b_coolFunction);
f2 = static_cast<void(*)(int)>(b_coolFunction);
f1();
f2(7);
//example from boost::function documentation. No cast required.
f3 = mul_ints;
std::cout << f3(5,3) << std::endl;
}
Compiled with g++-4.4.4, this outputs:
Calling a_coolFunction()
Calling a_coolFunction(5)
Calling b_coolFunction()
Calling b_coolFunction(7)
15
The biggest limitation is that the types of f1,f2, etc cannot change, so any function you assign to them must have the same signature (i.e. void(int) in the case of f2).
The simple way could be storing pointers to functions, and change them od demand.
But the better way is to use something similar to abstract factory design pattern. The nice generic implementation can be found in Loki library.
In C you would typically do this with a struct containing function pointers:
struct functiontable {
void (*someCoolFunction)(void);
void (*anotherCoolFunction)(int);
};
const struct functiontable table_a = { &a_someCoolFunction, &a_anotherCoolFunction };
const struct functiontable table_b = { &b_someCoolFunction, &b_anotherCoolFunction };
const struct functiontable *ftable = NULL;
To switch the active function table, you'd use:
ftable = &table_a;
To call the functions, you'd use:
ftable->someCoolFunction();

C++ Function List

I'm working on a fairly complex project, a custom encryption routine if you will (just for fun) and I've run into this issue in designing my code layout.
I have a number of functions that I want to be able to call by index. Specifically, I need to be able to call one randomly for the encrypt process, but then address that by a specific index in the decrypt process.
I was considering a classic function array, but my main concern is that a function array would be tricky to maintain, and a little ugly. (The goal is to get each function pair in a separate file, to reduce compile times and make the code easier to manage.) Does anyone have a more elegant C++ solution as an alternative to a function array? Speed isn't really an issue, I'm more worried about maintainability.
-Nicholas
What's wrong with function array?
You need to call functions by index. So they must be put into some "indexable by index" structure somehow. Array is probably the simplest structure that suits this need.
Example (typing out of my head, might not compile):
struct FunctionPair {
EncodeFunction encode;
DecodeFunction decode;
};
FunctionPair g_Functions[] = {
{ MyEncode1, MyDecode1 },
{ MySuperEncode, MySuperDecode },
{ MyTurboEncode, MyTurboDecode },
};
What is "ugly" or "hard to maintain" in the approach above?
You could write something like:
class EncryptionFunction
{
public:
virtual Foo Run(Bar input) = 0;
virtual ~MyFunction() {}
};
class SomeSpecificEncryptionFunction : public EncryptionFunction
{
// override the Run function
};
// ...
std::vector<EncryptionFunction*> functions;
// ...
functions[2]->Run(data);
You could use operator() instead of Run as the function name, if you prefer.
An object with an operator() method defined can act a lot like a function but be generally nicer to work with.
Polymorphism could do the trick: you couldf follow the strategy pattern, considering each strategy to implement one of your functions (or a pair of them).
Then create a vector of strategies, and use this one instead of the function list.
But frankly, I don't see the problem with the function array; you can easily create a typedef to ease the readability. Effectifely, you will end up with exactly the same file structure when using the strategy pattern.
// functiontype.h
typedef bool (*forwardfunction)( double*, double* );
// f1.h
#include "functiontype.h"
bool f1( double*, double* );
// f1.c
#include "functiontype.h"
#include "f1.h"
bool f1( double* p1, double* p2 ) { return false; }
// functioncontainer.c
#include "functiontype.h"
#include "f1.h"
#include "f2.h"
#include "f3.h"
forwardfunction my_functions[] = { f1, f2, f3 };
The function declaration and definitions are in separate files - compile time is ok.
The function grouping is in a separate file, having a dependency to the declarations only
You could take a look at the Boost.Signals library. I believe it has the ability to call its registered functions using an index.
Try Loki::Functor class. More info at CodeProject.com
You need to use an array of function pointers. The only catch is that all the functions have to have basically the same prototype, only the name of the function and passed argument names can vary. The return type and argument types (as well as the number of arguments and order) must be identical.
int Proto1( void );
int Proto2( void );
int Proto3( void );
int (*functinPointer[3])( void ) =
{
Proto1,
Proto2,
Proto3
};
Then you can do something like this:
int iFuncIdx = 0;
int iRetCode = functinPointer[iFuncIdx++]();
If you looked in boost::signals library, you'll see an example very nice, that is very elegant:
Suppose you have 4 functions like:
void print_sum(float x, float y)
{
std::cout << "The sum is " << x+y << std::endl;
}
void print_product(float x, float y)
{
std::cout << "The product is " << x*y << std::endl;
}
void print_difference(float x, float y)
{
std::cout << "The difference is " << x-y << std::endl;
}
void print_quotient(float x, float y)
{
std::cout << "The quotient is " << x/y << std::endl;
}
Then if you want to call them in a elegant way try:
boost::signal<void (float, float)> sig;
sig.connect(&print_sum);
sig.connect(&print_product);
sig.connect(&print_difference);
sig.connect(&print_quotient);
sig(5, 3);
And the output is:
The sum is 8
The product is 15
The difference is 2
The quotient is 1.66667