How to collect each parameter of a function in an array? - c++

I am currently in a code optimization phase and I would need help: I have a large number of functions taking as parameters std::strings and in which these std::strings are transformed in doubles using std::stod. I would like to be able to create a "gateway" function that would allow all the parameters of the function to be changed at once. I had thought of a function using variadic templates. Can you help me, please? This is an example of one of my functions:
std::optional<d> rectangle(const std::string& length, const std::string& width) {
if (others::is_type<double>(length) && others::is_type<double>(width)) {
d length_ = stod(length);
d width_ = stod(width);
return std::round((length_ * width_) * options::rounder) / options::rounder;
}
return {};
}
If you want me to add more details or to detail the other functions used in this one, ask me in comments. I already thank the all of you who'll answer.
To answer the first comment : the gateway function would collect the parameters of an other function (I don't know how for the moment), verify that they are strings and then to convert them to double. The aim would be to be able to just use this function and not to write "double ... = stod(...)" all the time (cause I have a really big number of functions).

Related

Explaining C++ (C Binding Library) Function

I'm trying to understand a Function/Method in a Library in order to port it to Java however some parameters don't make any sense to me and reading the source code the library is based on is not helping.
Function (Note the API has few comments (We can also ignore the calc handle since it's got a supplier method))
Ssr calc_ssr(CalcHandle *calc, NoteInfo *rows, size_t num_rows, float music_rate, float score_goal) {
std::vector<NoteInfo> note_info(rows, rows + num_rows);
auto skillsets = MinaSDCalc(
note_info,
music_rate,
score_goal,
reinterpret_cast<Calc*>(calc)
);
return skillset_vector_to_ssr(skillsets);
}
NoteInfo Struct
struct NoteInfo
{
unsigned int notes;
float rowTime;
};
MinaSDCalc
// Function to generate SSR rating
auto
MinaSDCalc(const std::vector<NoteInfo>& NoteInfo,
const float musicrate,
const float goal,
Calc* calc) -> std::vector<float>
{
if (NoteInfo.size() <= 1) {
return dimples_the_all_zero_output;
}
calc->ssr = true;
calc->debugmode = false;
return calc->CalcMain(NoteInfo, musicrate, min(goal, ssr_goal_cap));
}
Calc expected input file data (Only care about the #Notes: ...)
Pastebin
Question
What is NoteInfo in calc_ssr, I don't know any C or C++ so the *rows to me just seems like a pointer to a Noteinfo instance, however the MinaSDCalc methods requires an Array/Vector which using a pointer to a single instance doesn't make sense to me (pairing this with the fact that NoteInfo needs another parameter rowTime which I think is time of Note occurrence in the file which means that value must not be constant otherwise the produced result would be inaccurate)
Github Project: https://github.com/kangalioo/minacalc-standalone (The code alone may not explain enough but it's worth a try; best to look at API.h and discern what's used from there. Though I do warn you a lot of the Code is esoteric)
Sorry if this doesn't make much sense but I've been looking into this since June/July and this API is the closest abstraction from the bare C++ code I could find.
NoteInfo * rows here is pass by pointer. So, rows actually is a pointer to an instance of type NoteInfo. This is one of the ways to pass arrays in c++ to a function. Since arrays are contiguous in memory so we can just increment the pointer by one and get the next element of the array.
for example look at these three ways to do exactly one thing, parameter to pass an array to a function :-
1. void myFunction(int *param) {}
2. void myFunction(int param[10]) {}
3. void myFunction(int param[]) {}
Look into this link for more understanding : https://www.tutorialspoint.com/cplusplus/cpp_passing_arrays_to_functions.htm
Also search for pass by pointer and pass by reference to look into different ways of passing arguments in c++.
2.however the MinaSDCalc methods requires an Array/Vector which using a pointer to a single instance doesn't make sense to me: as to this question of yours, you can now see MinaSDCalc is actually getting an array and not a single instance as passing the pointer is also one of the ways of passing an array in c++.

How to call a specific function from an array of functions?

I'm working on building a watch based on the Arduino/ATMega. The primary goal for now is to switch between "modes” (different functions) by pressing a button on the side. Initially, I had a long if statement like this:
if (counter == 0)
mode1();
enter code
else if (counter == 1)
mode2();
.... Repeat....
But that seems inefficient. So, I tried to make an array of the functions without actually calling them, and then call the indexed function later. The code segment is as follows (Apologies for the mess, it’s very much a WIP)
int Modes[3] = {showTime,flashlight,antiAnxiety} //these are all void functions that are defined earlier.
int scroller(){
int counter = 0;
int timeLeft = millis()+5000;
while (timer <= millis()){
...more code...
}
Modes[counter]();
}
However, when I try to compile that, I get an error:
Error: expression cannot be used as a function.
That logic works in Python, so I’m assuming there’s a concept I don’t know that gets abstracted away in higher-level languages. I’m quite willing to learn it, I just need to know what it is.
The type is wrong - instead of int you need void (*)() as type (because you have an array of void someFunction() function pointers, not an array of integers - and while the former can be converted to the latter in a way, as memory address, you cannot call an integer).
void (*Modes[3])() = {showTime, flashlight, antiAnxiety};
This code becomes easier to understand with a type definition:
typedef void (*func_type)();
func_type Modes[3] = {showTime, flashlight, antiAnxiety};

Matlab legacy_code Tool - Writing a wrapper functio to catch an array

currently I'm trying to use a C/C++ Code based Library in Matlab/Simulink by means of the Matlab legacy_code tool. I am very new to this, please have some patience with me.
I stumbled upon the problem, that I got class members which return an array.
What I did upon now is to follow the Matlab legacy-code examples, especially this one:
Integrate External C++ Object Methods
As far as I can see, the legacy_code tool demands a wrapper function to be wrapped around a method call, so basicaly I could, within this wrapper function manipulate the return value of the called methad any way necessary. This far no problem.
But, I'm not certain how to receive an array of information from the called method an then pass this array to Matlab/Simulink.
e.g. A method's return value is an pointer pointing at an array of information of which, let us assume, we know the length of valid information it holds.
/* Simple example */
uint8_t* BUS::answerRcvd()
{
static int r[10];
int i;
srand( (unsigned)time( NULL ) );
for ( i = 0; i < 10; ++i)
{
r[i] = rand();
}
return r;
}
Is there a way to create a wrapper function for such a method that would receive an array of information and pass it along to matlab?
Might there be a possibility to handle that array as e.g. single values of uint8_t (if way stay with the given example) and pass these like in an ordinary matlab function?
[a,b,c] = function()
I'm open to any suggestion, thank you very much in advance.
Ok, looks like I found a Solution to my problem.
As a wrapper function its possible to use the following pattern
void myfunc(double u1, double u2, double u3, double *y1, double *y2)
{
*y1=u1;
*y2=(u2+u3)/2;
}
This wrapper function the is then interfaced by the Legacy Code Tool (LCT) as followed:
def = legacy_code('initialize')
def.OutputFcnSpec = 'void myfunc(double u1, double u2, double u3, double y1[1], double y2[1])'
Simple as that. On C/C++ code use pointer nomenclature / syntax, on Matlab use array nomenclature / syntax.
I hope, this will help some people like me who need a solution to interface with legacy code which should not only accept multiple inputs, but multiple outputs as well.
In hindsight the option tuuse pointers is pretty obvious, but if you don't knoe how to teach your LCT how to interface with it, it easily becomes an tiring task.

c++ class function aliases

I was wondering if there was a simple way to write an alias of a c++ class function. For instance, if I have some list container object, a logical function would be
int list::length() { return len; }
But another logical alias that programmers might use could be
int list::size() { return len; }
So, instead of writing both functions with their full body, is there any way to make list::size() an alias of list::length() such that it isn't a duplicate when compiled, but rather references the same function?
I've read that you can do this with #define, but I don't want to cause any confusion with other code-names somewhere totally out of scope (i.e. a 'size' variable).
I've also read that function pointers can fix it, but that isn't exactly an alias (since it has to apply de-referencing), nor can function pointers be given a declaration, giving it a confusing help-line to users (I would think), plus the confusion if ever I need to nest my code inside another object (I have to adjust the scope).
One of my guesses is, will the following be taken as a direct function alias by most optimizing compilers:
inline int list::length() { return len; }
inline int list::size() { return length(); }
Or, is there any strict 'alias' syntax for c++? (I couldn't find any - wasn't sure)
So then, what would be the most efficient way of doing this?
EDIT: I've accepted the answer simply to wrap up the question, since it's only a curiosity of mine. Anyone with good information, please add comments or answer, and I may even change my answer.
I would not use the preprocessor and #define to do this. In general preprocessor should be a last resort in C++. See this C++ FAQ on inline functions which also contains a section on the various evils of using macros of the preprocessor.
The approach I would use would be to have a function that will have several different aliases with a more complicated function and interface you would do something like the following:
int list::length(string xString, int iValue) {
int iReturnValue = 0; // init the return value
// do stuff with xString and iValue and other things
return iReturnValue;
}
Then do something like the following for an alias.
inline int list::size(string xString, int iValue) {return length(xString, iValue);}
The inline should basically just replace the alias with the actual function call.
See also this stack overflow posting Giving a function implementation more than one name. It provides some reasons why you might not want to do this.

good practice - similarly named variables

Trivial issue, but comes up a lot for me, and I imagine others too. Does anybody have a really good, really clever solution?
void some_function (obj &A, obj &B)
{
// do stuff with A...
//e.g.
double number_A = (value - A.member_func() ) * A.other_func();
// do stuff with B. similar BUT NOT EXACTLY like A...
//e.g.
double number_B = (value + B.member_func() ) * A.other_func();
// !!!!
// Big time TYPO - should say "B.other_func()", not "A.other_func()" !!!!
// !!!!
}
Any good guards against these types of errors?
I often have to work on two analogous variables, say one named version "A" and the other "B".
Because the code for each one is similar, I often use the code that worked on "A" as a "template" (i.e. copy & paste) for the code that works on "B" - making the small adjustments so that the code becomes appropriate for B.
Becuase I am human, I sometimes forget to change "A" to "B" in certain locations when copying the code. If I am lucky, this will cause the program to crash. Either way, this is disastrous.
Does anybody know any clever tricks for preventing such typos?
I've thought of...
enclosing brackets { } to try to restrict the scope of variables - but if objects A and B are in the function arguments, then this doesn't solve it.
dividing every function into sub-functions - one for A and one for B. This is a bit cumbersome from the developer perspective (passing/returning many of variables).
work only with pointers to the objects themselves - not the actual objects. This way we can { scope-control } the pointers. Also cumbersome, (and the overhead for defining a pointer is negligible, even if I call the function very, very often, right?)
In the example you give, the best defence is to do as little as possible in each function:
void some_function (obj &A, obj &B)
{
double number_A = do_stuff(A);
double number_B = do_similar_stuff(B);
}
double do_stuff(obj &A) {
return (value - A.member_func() ) * A.other_func();
}
// EITHER
double do_similar_stuff(obj &A) {
// no variable rename when copying == no problem
return value + A.member_func() ) * A.other_func();
}
// OR
double do_similar_stuff(obj &B) {
// A not in scope == very brief problem until compiler tells us
return value + B.member_func() ) * A.other_func();
// Beware, also, the nightmare scenario that there's some *other*
// `A` in scope, so this *still* compiles. For that reason, prefer
// the other option unless there's some good reason why this parameter
// should be `B`, and don't name member function parameters the same
// as data members etc.
}
Alternatively, you could make the relation between the two kinds of "stuff" explicit. Assuming that the unmatched parenthesis in your B code is supposed to go in the same place as the A. It all depends whether there really is a logical relationship between the two similar-looking operations:
void some_function (obj &A, obj &B)
{
double number_A = do_stuff(A, true);
double number_B = do_stuff(B, false);
}
double do_stuff(obj &A, bool subtract) {
// yeah, never call variables "tmp". Unless you have no context
// to give them meaning.
// Depending on the type of `tmp`, there might be a better way to
// write this, using multiplication by -1. But let's not assume, we'll do
// one refactor at a time.
auto tmp = subtract ? value - A.member_func() : value + A.member_func();
return tmp * A.other_func();
}
Other examples will vary. As you say it can be tiresome to write, but it has a number of benefits other than catching this error. Not least is that it will direct you towards writing your code in a way that you try to avoid passing/returning many variables. As a consequence, each line of your code affects fewer other things in the program, which is basic code hygiene.
It may also mean you can test that your formula with A is correct independently of whether your formula with B is correct, and sundry other benefits of short functions.
I have a few ideas in mind
you could use snippets if your editor supports them or move to an editor/ide which has support for them (personally I use kdevelop and snippets are very useful as they replace all occurences of a snippet variable)
you could also use refactoring (in a separate function if you
already used the names this one)
also selecting a piece of code and doing replace all in selection
might help
using defines is also an option
Still, going with a smarter IDE is the best in my opinion.
I think your best bet is not have similar function names in other classes. Also, having unit tests coupled with peer code reviews should catch these errors most of the time. However, there have been many times in SW history where these types of errors are never caught until many days, months, or years later.