Storing 2 variables at once from a tuple function - c++

I have a tuple function that returns a tuple of the form
<node*,int>
Is there a way to store 2 values at once without creating another tuple. I know we can do
n,score=tuplefunct(abc);
in python. But if I want to store both return values in c++ without making another tuple i need to call twice
n=get<0>(tuplefunct(abc);
score=get<1>(tuplefunct(abc));
is there any alternative to this in c++ to store the values at once.

You dont need to call the function twice (note that there is no "another tuple" involved, the function returns one and thats what you use):
auto x = tuplefunct(abc);
auto n = get<0>(x);
auto score = get<1>(x);
If you have C++17 available you can use structured bindings
auto [n,score] = tuplefunct(abc);
Or to get close to that without C++17, you can use std::tie (from C++11 on):
node* n;
int score;
std::tie(n,score) = tuplefunct(abc);

Related

Any straightforward way to capture and initialize multiple return values from function

In my project there are few functions that return multiple values with the help of tuple and they are used numerously. So I just want to know is there any way in c++ with which I can capture and initialize individual values that are returned by that function call. Below example will explain this question better
#include <iostream>
#include <string>
#include <tuple>
std::tuple<std::string,int,int> getStringWithSizeAndCapacity()
{
std::string ret = "Hello World !";
return make_tuple(ret,ret.size(),ret.capacity());
}
int main()
{
//First We have to declare variable
std::string s;
int sz,cpcty;
//Then we have to use tie to intialize them with return of function call
tie(s,sz,cpcty) = getStringWithSizeAndCapacity();
std::cout<<s<<" "<<sz<<" "<<cpcty<<std::endl;
//Is there a way in which I can directly get these variables filled from function call
//I don't want to take result in std::tuple because get<0>,get<1> etc. decreases readibility
//Also if I take return value in tuple and then store that in individual variables then I am wasting
//tuple as it will not be used in code
return 0;
}
Is there a way in which I can directly get these variables filled from function call I don't want to take result in std::tuple because get<0>,get<1> etc. decreases readibility
Also if I take return value in tuple and then store that in individual variables then I am wasting tuple as it will not be used in code
I understand that the use of std::get<>() decreases readability, but you can try to improve it with some comments
// get the size of the returned string (position 1)
auto sz = std::get<1>(getStringWithSizeAndCapacity());
Anyway, it seems to me that the right way to improve readability is the use of std::tie(), and isn't clear to me what's wrong with it for you, or (starting from C++17) also structured binding declarations
auto [ s, sz, cpcty ] = getStringWithSizeAndCapacity();
If you want avoid to name unused variables (say you are not interested in capacity, by example) you can use std::ignore
std::string s;
int sz;
std::tie(s,sz,std::ignore) = getStringWithSizeAndCapacity();
Unfortunately std::ignore can't be used (as far I know) with new C++17 structured binding (maybe something similar from C++20?).

How to treated pair integer as separated variable?

Is there any way to separate paired integer?
first i declare queue in a way:
typedef pair<int,int>pr;
queue<pr>que;
i can easily push separate variable in it. e.g.
que.push(make_pair(c,p));
now when i take value from queue. i have to take in any paired variable like myp.
pair<int , int> myp = que.front();
Now, is there any way to take value in two separate variable from myp or directly take value in separate variable from queue?
is there any way to take value in two separate variable from myp
Yes:
auto [c, p] = que.front();
Those are called Structured Bindings and have been part of the language since C++17.
is there any way in C++98?
Yes. If you take a look at the documentation of std::pair, you'll find that it has two members, first, and second.
int a = myp.first;
int b = myp.second;

Random normal distribution by Gaussian in C++

I have my function in Python for normal distribution. I need to convert it to C++ and i am not familiar with language.
Here is my Python:
def calculation(value):
sigma = 0.5
size = 10000
x = 200
x_distribution = np.random.normal(value, sigma, size)
for i in x_distribution:
x.append(i)
return x
And it works as expected. I am trying to re-write same thing in C++ and found only the Link and where the "std::normal_distribution<> d{5,2};
" has to make magic. But i could not figure it out how to implement.
Here what i have tried and it is failing.
# include frame.distribution
Frame DistributionModel(x_mu, x_sigma)
{
// Motion model;ignore it
model = std::normal_distribution<> d{x_mu,x_sigma};
return model;
}
Please, help me. Looking for any hints. Thanks.
Well, trouble without end...
# include frame.distribution
Syntax for inclusion is:
#include <name_of_header_file>
// or:
#include "name_of_header_file"
(The space in between # and include does not harm, but is absolutely uncommon...)
Frame DistributionModel(x_mu, x_sigma)
C++ is a strongly typed language, i. e. you cannot just give variables a name as in Python, but you need to give them a type!
Frame DistributionModel(double x_mu, double x_sigma)
Same for local variables; type must match what you actually assign to (unless using auto)
std::normal_distribution<double> nd(x_mu, x_sigma);
This is a bit special about C++: You define a local variable, e. g.
std::vector<int> v;
In case of a class, it gets already constructed using its default constructor. If you want to call a constructor with arguments, you just append the call to the variable name:
std::vector<int> v(10); // vector with 10 elements.
What you saw in the sample is a feature called "uniform initialisation", using braces instead of parentheses. I personally strongly oppose against its usage, though, so you won't ever see it in code I have written (see me constructing the std::normal_distribution above...).
std::normal_distribution is defined in header random, so you need to include it (before your function definition):
#include <random>
About the return value: You only can return Frame, if the data type is defined somewhere. Now before trying to define a new class, we just can use an existing one: std::vector (it's a template class, though). A vector is quite similar to a python list, it is a container class storing a number of objects in contiguous memory; other than python lists, though, the type of all elements stored must be the same. We can use such a vector to collect the results:
std::vector<double> result;
Such a vector can grow dynamically, however, this can result in necessity to re-allocate the internal storage memory. Costly. If you know the number of elements in advance, you can tell the vector to allocate sufficient memory in advance, too:
result.reserve(max);
The vector is what we are going to return, so we need to adjust the function signature (I allowed to give it a different name and added another parameter):
std::vector<double> getDistribution(double x_mu, double x_sigma, size_t numberOfValues)
It would be possible to let the compiler deduce the return type, using auto keyword for. While auto brings quite a lot of benefits, I do not recommend it for given purpose: With explicit return type, users of the function see right from the signature what kind of result to expect and do not have to look into the function body to know about.
std::normal_distribution now is a number generator; it does not deliver the entire sequence at once as the python equivalent does, you need to draw the values one by another explicitly:
while(numberOfValues-- > 0)
{
auto value = nd(gen);
result.push_back(value);
}
nd(gen): std::normal_distribution provides a function call operator operator(), so objects of can be called just like functions (such objects are called "functors" in C++ terminology). The function call, however, requires a random number generator as argument, so we need to provide it as in the example you saw. Putting all together:
#include <random>
#include <vector>
std::vector<double> getDistribution
(
double x_mu, double x_sigma, size_t numberOfValues
)
{
// shortened compared to your example:
std::mt19937 gen((std::random_device())());
// create temporary (anonymous) ^^
// instance and call it immediately ^^
// afterwards
std::normal_distribution<double> nd(x_mu, x_sigma);
std::vector<double> result;
result.reserve(numberOfValues);
while(numberOfValues-- > 0)
{
// shorter than above: using result of previous
// function (functor!) call directly as argument to next one
result.push_back(nd(gen));
}
// finally something familiar from python:
return result;
}
#include<iostream>
#include<random>
#include<chrono>
int main() {
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator(seed);
std::normal_distribution<double> distribution(0.0, 3.0);
double number = abs(distribution(generator));
std::cout << number;
std::cin.get();
return 0;
}
This may help, create a random number using gaussian with mean=0.0 and std_dev= 3.0

Using SelectFirst with a condition that relies on the input

I'm trying to find the first instance in a list, a, for which the element is not a member of another list, b. I'm thinking to use something similar to this:
a = {r,j,k};
b = {r,m,n};
firstnonmatch = SelectFirst[a,MemberQ[b,a_i]==False]
where firstnonmatch would return m. But I'm not sure how to refer to elements of the list in the conditions when using SelectFirst[]. Is there a good way to do this?
the crit argument needs to be a function, here you use a pure function:
a = {r,j,k};
b = {r,m,n};
SelectFirst[a,!MemberQ[b,#]&]
j

boost function with optional parameters

I have a map containing boost::function values, as defined below:
std::map <std::string, boost::function<std::string (std::string, int)> > handlers;
Let us say I define the following function:
using namespace std;
string substring (string input, int index = 0){
if (index <= 0){
return input;
}
stringstream ss;
for (int j = index; j<input.length(); j++){
ss << input[j];
}
return ss.str();
}
I would like to be able to store this in the handlers map, but WITH it's optional parameter. Does boost have a way to perform this? I have looked at boost::optional, but that doesn't seem to do what I want.
EDIT
To give a little more background, there are a few handlers that require extra arguments, such as a pointer to a dictionary (typedef std::map < std::string, std::string > dictionary) or something, because they make changes to that dictionary. However, the majority of the handlers do not touch the dictionary in question, but, in order to store them all in the same map, they all must take the same arguments (have the same template for boost::function). The goal is to make the functions that don't deal with the dictionary at all usable without having to either A) create a dictionary for the sole purpose of passing it and not using it or B) copy the code verbatim into another function that doesn't require that argument.
The code above is a simplified example of what I am doing.
The short answer: This is not possible in C++ without a lot of additional code.
The long answer:
Default values for function arguments in C++ are only used when they are needed in a context where the function's name appears. If you call a function through other means (like a function pointer, or boost::function/std::function, the information about there possibly being default arguments is not available to the compiler, so it can't fill them in for you.
As a background, this is how default arguments work in C++:
When you have the expression substring(MyString) (with std::string MyString = "something"), then the compiler looks for all functions called substring and finds string substring(string, int=0). This function takes two parameters, one of which can have a default value, which makes the function viable. To actually call the function, the compiler changes the source code so that it reads substring(MyString, 0) and proceeds to generate code based on that adaptation.
To be able to use default values with an indirect call, like through boost::function, you effectively have to emulate the default argument mechanism of the compiler.