How a local variable can be taken in this C++ lambda expression? - c++

In the following code:
#include "Simple_window.h"
#include "Graph.h"
int fac(int n) // factorial(n); n!
{
int r = 1;
while(n>1) {
r *= n;
--n;
}
return r;
}
double term(double x,int n) { return pow(x,n)/fac(n); }
double expe(double x,int n) // sum of n terms for x
{
double sum = 0;
for(int i = 0; i<n; ++i) sum += term(x,i);
return sum;
}
int main() {
Simple_window win {Point{100,100},xmax,ymax,""};
for(int n = 0; n<50; ++n) {
ostringstream ss;
ss << "exp approximation; n==" << n;
win.set_label(ss.str());
// get next approximation:
Function e {[n](double x) { return expe(x,n); },
-10,10,Point{300,300},200,30,30; // ***this line doesn't compile***
win.attach(e);
win.wait_for_button();
win.detach(e);
}
}
From the book "Principles and Practice using C++" by Stroustrup, the local variable n isn't taken when I try to compile it, and gives the error message:
No instance of the constructor Graph_lib::Function::Function coincides with the argument list
What is the problem?
By the way, the support code used for the books is https://web.archive.org/web/20191217104940/http://www.stroustrup.com/Programming/PPP2code

Your post is not close to a Minimal Reproducible Example
Here is an example for Minimal Reproducible Example.
In Graph.h Function takes a variable of Fct.
Where Fct is typedef double Fct(double);.
According to this post, lambda expression doesn't translate to function automatically, unless it doesn't create closure object by capturing nothing.
Check this example
typedef double Fct ( double );
typedef double bct ( double, int );
struct Foo{
Foo( Fct f ){};
};
struct bar{
bar( bct f){};
};
int main(){
int n(1);
Foo f{ [](double x){ return x; } };
//Foo f{ [n](double x){ return x*n; } }; // <=== this won't compile
bar b{[](double x, int n){return x*n;}};
}
To pass the n into function f without closure, you may
Change signature from typedef double Fct ( double ); to typedef double Fct ( double, int ); Like my example of bar
Write a function with a constant n.
(Strongly not suggested, unless you never maintain the code ) Global variable to make it possible to change n outside the function.

Related

Passing values from a function to another function

I'm new in C++ programming world and I have not understood yet if it's possible (and how) to use an output from a function as input to another function.
#include <iostream>
using namespace std;
int func(int l, int m) {
int x = l * m;
return x;
}
int code(x?) {
...
}
I would like to use output from func (the value x) as an input for code.
Is it possible? How could I do that?
Thanks for the help
EDIT 1:
Really thanks for the answers. Is it possible also to pass values between functions using pointers?
Functions only "have" values while they are executed.
You can either call the first from the second funtion,
or call the first function, read the return value into a variable and give that value as parameter to the second,
or call the second and give one of its parameters directly as return value from a call to first function.
Here are some examples of the three options, using 1,2,3 as arbitrary integers.
Variant 1:
int func(int l, int m) {
int x = l * m;
return x;
}
int code(void) {
int ValueFromOtherFuntion=func(1,2);
return 3;
}
Variant 2:
int func(int l, int m)
{
int x = l * m;
return x;
}
int code(int XfromOtherFunction)
{
return 3;
}
int parentfunction(void)
{
int ValueFromOtherFuntion=func(1,2);
return code(ValueFromOtherFunction);
}
Variant 3:
int func(int l, int m)
{
int x = l * m;
return x;
}
int code(int XfromOtherFunction)
{
return 3;
}
int parentfunction(void)
{
return code(func(1,2));
}
Yes, what you are looking for is called function composition.
int sum(int a, int b)
{
return a + b;
}
int square(int x)
{
return x*x;
}
int main()
{
std::cout << square(sum(5, 4)); //will calculate (5+4)squared
}
When you write the functions, assume that you already have all the input and proceed just writing what you want that function to do.
As to when you use that function, use "nested functions" or a function inside a function as such:
code(func(l, m));
Function func will execute first and return the value x, thus leaving you with code(x) which will execute after. Its like pealing an onion: one layer to the other.
#include <iostream>
int func(int l, int m) {
int x = l * m;
return x;
}
void code(int x) { // argument type is the same as the return type of func
std::cout << x;
}
int main (){
int result = func(1 ,2); // either store it
code(func(1, 2)); // or pass it directly.
std::cout << result;
return -1;
}
You can call it in your main function (or in any other within scope for what matters):
code(func(l,m))

What is the appropriate manner to return a struct from a called function to a calling function in C++?

I have a function which takes in two int values, does some processing and then returns the processed values in the form of a struct to the calling function.
The following is my called function:
auto start_end(){
bool cond = false;
int xd = 0;
int yd = 0;
std::cout<<("Please enter a desired x coordinate")<<std::endl;
std::cin>>xd;
while(std::cin.fail()){
std::cout<<("That is not a valid integer. Please enter a valid x co-ordinate")<<std::endl;
std::cin.clear();
std::cin.ignore(256,'\n');
std::cin>>xd;
}
std::cout<<("Please enter a desired y coordinate")<<std::endl;
std::cin>>yd;
while(std::cin.fail()){
std::cout<<("That is not a valid integer. Please enter a valid y co-ordinate")<<std::endl;
std::cin.clear();
std::cin.ignore(256,'\n');
std::cin>>yd;
}
struct xy{int x_received; int y_received;};
return xy{xd,yd};
}
We can see that the struct xy returns two values xd, yd in the above function start_end().
The following is my calling function:
int main(int argc, const char * argv[]) {
std::cout <<("A-Star-Algorithm for Project 2 obstacle map")<<std::endl;
int x_start = 0;
int y_start = 0;
int init_point = start_end();
return 0;
}
So when I try to store the return values xd, yd in the variable init_point, I get the error:
No viable conversion from 'xy' to 'int'
Since, I got this error I tried to write the receiving variable as a 2 - index array:
int init_point[2] = start_end();
When I try to do in this way, I get the following error:
Array initializer must be an initializer list
My exact question : What is the appropriate manner in which I have to receive the values xd and yd returned by function start_end() when it is called inside function int main() ?
You need to move your struct into a place that can be seen by start_end and main:
struct xy { int x; int y; };
xy start_end()
{
...
return { xd, yd };
}
int main()
{
}
Then you can either assign it with auto or use the type name xy:
int main()
{
auto xy1 = start_end();
xy xy2 = start_end();
}
Or you can use std::pair or std::tuple.
std::tuple is to your relief (live)
#include <iostream>
#include <tuple>
auto start_end() {
auto x = 1, y = 2;
return std::make_tuple(x, y);
}
int main() {
int x, y;
std::tie(x, y) = start_end();
std::cout << x << ' ' << y << std::endl;
}

mem_fn to mem_fn of member

This is a follow-up question to
mem_fn to function of member object
This is the current code.
#include <vector>
#include <algorithm>
#include <functional>
struct Int
{
Int(int _x = 0) : x(_x) {}
int GetInt() const { return x; }
int x;
};
struct IntWrapper
{
IntWrapper(int _x = 0) : test(_x) {}
int GetWrappedInt() const { return test.GetInt(); }
Int test;
};
template<class ContainerT, class Mem> constexpr auto maxElem(const ContainerT& _container, Mem _Pm)
{
auto memFn = std::mem_fn(_Pm);
return memFn(std::max_element(_container.cbegin(), _container.cend(), [&](auto _rhs, auto _lhs) { return memFn(_rhs) < memFn(_lhs); }));
}
int main()
{
{
std::vector<Int> vec;
for (int i = 0; i < 10; ++i)
{
vec.push_back(i * 11 % 7); // some random values
}
int m = maxElem(vec, &Int::GetInt);
int n = maxElem(vec, &Int::x);
}
{
std::vector<IntWrapper> vec;
for (int i = 0; i < 10; ++i)
{
vec.push_back(i * 7 % 11); // some random values
}
int m = maxElem(vec, &IntWrapper::GetWrappedInt);
//int o = maxElem(vec, ???) // what if GetWrappedInt didn't exist?
}
return 0;
}
The original question was about retrieving the x value of the Int struct through anIntWrapper object. I used mem_fn for this because it doesn't seem to distinguish between a function returning an int and an int member variable (Seen in these lines:
int m = maxElem(vec, &Int::GetInt);
int n = maxElem(vec, &Int::x);
The solution for IntWrapper objects was to add .test
auto y = std::mem_fn(&Int::GetInt);
auto b = y(wrapper.test);
to the call. However, in the maxElem function, I cannot do this.
I'm wondering if there is a way to formulate the call in such a way that the mem_fn goes from the IntWrapper object directly to the int x variable (Without the helper function and assuming that all members are public).
//int o = maxElem(vec, ???) // what if GetWrappedInt didn't exist?
The original approach was auto y = std::mem_fn(&IntWrapper::test.GetInt); // ERROR, which of course does not compile, but shows the idea.
Thanks in advance!
You cannot use std::mem_fn with something different than a pointer to member (such as a pointer to member of member). So, you must use that. In your particular case, you can achieve that with
std::vector<IntWrapper> vec;
for (int i = 0; i < 10; ++i)
{
vec.push_back(i * 11 % 7); // some random values
}
auto m = maxElem(vec, &IntWrapper::GetWrappedInt);
However, I strongly advise you to use lambda expressions whenever possible. std::mem_fn should be considered as if deprecated, since, AFAIK, it serves no purpose that cannot be achieved at least as well by other means, i.e. a lambda.

Integration with quadrature and multiprecision boost libraries in C++

after searching i had found amazing code for integration by
quadrature boost library.
rather than
log(x)/(1+x)
want to integrate
(poly[0]+poly[1]*x+poly[2]*x^2+...+poly[n]*x^n)*log(x)/(1+x). But, i do not
know how to insert the vector
poly
to
struct f
or even how to call these operators from main function. The code :
#include<iostream>
#include<boost/math/constnats/constants.hpp>
#include<boost/multiprecision/cpp_dec_float.hpp>
#include <boost/numeric/quadrature/adaptive.hpp>
#include <boost/numeric/quadrature/kronrodgauss.hpp>
#include <boost/numeric/quadrature/epsilon.hpp>
using namespace std;
using boost::multiprecision::cpp_dec_float_50;
namespace quadrature=boost::numeric::quadrature;
struct f
{
double operator()(double x) const {
return (log(x)/(1+x); }
};
int main()
{
vector<cpp_dec_float_50> poly(0);
cpp_dec_float_50 p = 0;
for (int i=0;i<=n;i++)
{
p=polynomial(i,n);
poly.push_back(p);
}
double answer,error_estimate;
quadrature::adaptive().relative_accuracy(1e-5).absolute_accuracy(1e-7)
(f(),0.,1.,answer,error_estimate);
cout<<"ans"<<answer<<endl;
return 0;
}
cpp_dec_float_50 polynomial(int k ,int n)
{
.
.
.
}
Also, when changing the double operator, to cpp_dec_float_50 operator in
struct f
many problems arise. and the later type is necessary in my project. Any one can fix that ?
EDIT
i tried this, but i do sth wrong
#include<iostream>
#include <boost/numeric/quadrature/adaptive.hpp>
#include <boost/numeric/quadrature/kronrodgauss.hpp>
#include <boost/numeric/quadrature/epsilon.hpp>
#include<boost/math/constants/constants.hpp>
#include<boost/multiprecision/cpp_dec_float.hpp>
using namespace std;
using boost::multiprecision::cpp_dec_float_50;
namespace quadrature=boost::numeric::quadrature;
double polynomial(int k ,int n);
struct f
{ const cpp_dec_float_50 s=0;
vector<cpp_dec_float_50> poly;
cpp_dec_float_50 sum()const{
for(int i=0;i<=poly.size();i++)
s+=poly[i];
return s
}
double operator()(double x) const {
return
s*log(x)/(1+x); }
};
int main()
{
int n=2;
f fun;
cpp_dec_float_50 p = 0;
for (int i=0;i<=n;i++)
{
p=polynomial(i,n);
fun.poly.push_back(p);
}
double answer,error_estimate;
quadrature::adaptive().relative_accuracy(1e-5).absolute_accuracy(1e-7)
(fun,0.,1.,answer,error_estimate);
cout<<"ans"<<answer<<endl;
return 0;
}
double polynomial(int k ,int n)
{
return k;
}
Edit
when using Patstew suggestion
Two errors occur
Try something along the lines of:
struct f
{
vector<cpp_dec_float_50> poly;
double operator()(double x) const {
return (poly[0]+poly[1]*x+poly[2]*x^2+...+poly[n]*x^n)*log(x)/(1+x); }
};
int main()
{
f fun;
cpp_dec_float_50 p = 0;
for (int i=0;i<=n;i++)
{
p=polynomial(i,n);
fun.poly.push_back(p);
}
double answer,error_estimate;
quadrature::adaptive().relative_accuracy(1e-5).absolute_accuracy(1e-7)
(fun,0.,1.,answer,error_estimate);
cout<<"ans"<<answer<<endl;
return 0;
}
EDIT: RE you own answer, you never call sum (and s is const so you couldn't change it if you did) so s is always 0 and you will always get 0 as your answer. Also you are iterating all the way up to poly.size() in sum(), but poly[poly.size()-1] is the last element. I think you really want your sum function to calculate a polynomial? Try this:
#include<iostream>
#include <boost/numeric/quadrature/adaptive.hpp>
#include <boost/numeric/quadrature/kronrodgauss.hpp>
#include <boost/numeric/quadrature/epsilon.hpp>
#include<boost/math/constants/constants.hpp>
#include<boost/multiprecision/cpp_dec_float.hpp>
using namespace std;
using boost::multiprecision::cpp_dec_float_50;
namespace quadrature=boost::numeric::quadrature;
double polynomial(int k ,int n);
struct f
{
vector<double> poly;
double polysum(double x) {
double s = poly[0];
double p = 1;
for(int i=1;i<poly.size();i++) {
p = p*x;
s+= p*poly[i];
}
return s
}
double operator()(double x) {
return polysum(x)*log(x)/(1+x); }
};
int main()
{
int n=2;
f fun;
double p = 0;
for (int i=0;i<=n;i++)
{
p=polynomial(i,n);
fun.poly.push_back(p);
}
double answer,error_estimate;
quadrature::adaptive().relative_accuracy(1e-5).absolute_accuracy(1e-7)
(fun,0.,1.,answer,error_estimate);
cout<<"ans"<<answer<<endl;
return 0;
}
double polynomial(int k ,int n)
{
return k;
}

callback vs lambda

Suppose I have the following code that I wish to refactor:
int toFuture()
{
precalc();
int calc = 5 * foobar_x() + 3;
postcalc();
return calc;
}
int toPast()
{
precalc();
int calc = 5 * foobar_y() - 9;
postcalc();
return calc;
}
In classic-C, I would refactor this code into a worker() which accepts a function pointer that does the calculation: common code in worker(), specific code provided by function pointer.
With C++11, should I be using a lambda instead? If so, how would I implement it, in this case?
Edit: it just crossed my mind that a template may also work. How would a template implementation compare against the other two?
One approach:
template<typename CalcFuncT>
int perform_calc(CalcFuncT&& calcfunc)
{
precalc();
int const calc = std::forward<CalcFuncT>(calcfunc)();
postcalc();
return calc;
}
int main()
{
perform_calc([]{ return 5 * foobar_x() + 3; }); // toFuture
perform_calc([]{ return 5 * foobar_y() - 9; }); // toPast
}
If you are wanting a template approach using C++11 features, that could look as simple as:
template<typename FuncType>
auto calculation(FuncType&& func) -> decltype(func())
{
precalc();
auto ret = func();
postcalc();
return ret;
}
You would then simply call your calculation function and pass it either a lambda, a functor, or a function-pointer. Your only souce of difficulty in this instance would be if you passed a function that had a void return-type ... in that case you will get a compiler error (which is a good thing vs. a runtime error).
I'd say you're refactoring from the wrong side:
struct CalcGuard {
CalcGuard() { /* replaces precalc() */ }
~CalcGuard() { /* replaces postcalc() */ }
};
int toFuture()
{
return CalcGuard(), calc = 5 * foobar_x() + 3;
}
int toPast()
{
return CalcGuard(), calc = 5 * foobar_y() - 9;
}
There is a C/C++ way to do this, and a C++11 way. Neither way involves lambdas or templates.
The C/C++ way:
double MyFunc (int x, float y) { return x + y ; }
int main()
{
double (*pf) (int, float) ;
pf = MyFunc ;
pf (101, 202.0) ;
}
The C++11 way:
#include <functional>
double MyFunc (int x, float y) { return x + y ; }
int main()
{
std::function<double (int, float)> f ;
f = MyFunc ;
f (51, 52.0) ;
}
In either case, you just pass pf or f to your refactored function as a parameter. Using lambdas or templates is overkill here.