I give you a simple snippet of code:
#include <functional>
#include <iostream>
using namespace std;
void module2(int x, int y)
{
cout << "\n " << __PRETTY_FUNCTION__ << ":\t x = " << x << "\t y = " << y;
}
void module3(int x, int y, int z)
{
cout << "\n " << __PRETTY_FUNCTION__ << ":\t x = " << x << "\t y = " << y << "\t z = " << z;
}
int main()
{
using namespace std::placeholders;
int a = 39;
int b = 7;
int c = 3;
auto func_m2 = bind(&module2, _1, _2);
func_m2(a, b); // OK
auto func_m2_PH = bind(&module2, _2, _1);
func_m2_PH(b, a); // OK
//---------------------------------------------------------
auto func_m3 = bind(&module3, a, b, c);
func_m3(); // OK
cout << "\n With PlaceHolders:";
auto func_m3_PH_0 = bind(&module3, _1, _2, _3);
func_m3_PH_0(a, b, c); // OK
auto func_m3_PH_1 = bind(&module3, _2, _1, _3);
func_m3_PH_1(b, a, c); // OK
auto func_m3_PH_2 = bind(&module3, _3, _1, _2);
func_m3_PH_2(c, a, b); // KO !!!
auto func_m3_PH_3 = bind(&module3, _3, _2, _1);
func_m3_PH_3(c, b, a); // OK
auto func_m3_PH_4 = bind(&module3, _1, _3, _2);
func_m3_PH_4(a, c, b); // OK
auto func_m3_PH_5 = bind(&module3, _2, _3, _1);
func_m3_PH_5(b, c, a); // KO !!!
return 0;
}
link to coliru
When the first argument is a function that takes 2 arguments everything is fine: the code works as I expect.
However when the first std::bind's parameter is a function with 3 (or more) arguments the code stops working as I expect (these cases are marked with 'KO !!!' )
But, what do I expect from std::bind and its placeholders?
In this particular case I expect the output:
void module3(int, int, int): x = 39 y = 7 z = 3
every time that I invoke the function object generated from
bind(&module3, etc...)
but, more in general:
I expect that the parameter that replaces the placeholder named '_K' will be the K-th parameter passed to the underlying function (i.e. the first parameter of the std::bind).
What is wrong? My understanding of the std::bind or there is a bug in this function template?
Thanks for your time.
You have it backwards. The _K placeholder defines the mapping from the Kth argument passed to the generated functor (the result of bind) to the position of the placeholder in the parameters of the bound function. So putting _3 in the first argument position of bind means that the first argument given to the bound function will be the third parameter given to the generated function.
The other cases worked because your reversed logic just so happened to be the same as the correct version.
Related
I am a new man on using spirit x3, I read some document from official site or from other github repositories. But, I can not find how to parse into a class with parameters. I referred to the former question: Boost-Spirit (X3) parsing without default constructors
I wrote a sample to test it, I will present my codes in the following area. My pain is how to use x3::_attr, and how to pass parsed parameters to the class constructor?
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <vector>
struct MyPair {
MyPair(int x, int y) : mx(x), my(y) {};
int mx;
int my;
};
class MyDu {
public:
MyDu() {};
MyDu(int x, int y) : mx(x), my(y) {};
int mx;
int my;
};
int main()
{
namespace x3 = boost::spirit::x3;
using x3::int_;
std::vector<MyPair> pairs;
MyDu myDu;
char const *first = "11:22", *last = first + std::strlen(first);
//auto pair = x3::rule<struct pair_, std::vector<MyPair> >{}
// = (int_ >> ':' >> int_)
// [([&](auto& ctx) {
// auto& attr = x3::_attr(ctx);
// using boost::fusion::at_c;
// return x3::_val(ctx).emplace_back(at_c<0>(attr), at_c<1>(attr));
// })]
//;
auto pair = x3::rule<class MyDu_, MyDu >{}
= (int_ >> ':' >> int_)
[([&](auto& ctx) {
auto& attr = x3::_attr(ctx);
using boost::fusion::at_c;
//return x3::_val(ctx)(at_c<0>(attr), at_c<1>(attr));
ctx = MyDu(at_c<0>(attr), at_c<1>(attr));
return x3::_val(ctx);
})]
;
//bool parsed_some = parse(first, last, pair % ',', pairs);
bool parsed_some = parse(first, last, pair, myDu);
if (parsed_some) {
std::cout << "Parsed the following pairs" << std::endl;
//for (auto& p : pairs) {
// std::cout << p.mx << ":" << p.my << std::endl;
//}
std::cout<<myDu.mx<<","<<myDu.my<<std::endl;
}
system("pause");
}
Any one who can fix my error, and parse into a class in my code ? Thanks!
Perhaps you were missing the way to assign to the rule's value using _val:
Live On Coliru
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <vector>
struct MyDu {
MyDu(int x, int y) : mx(x), my(y){};
int mx;
int my;
};
int main() {
namespace x3 = boost::spirit::x3;
using x3::int_;
MyDu myDu{1,2};
std::string const s = "11:22";
auto assign = [](auto& ctx) {
using boost::fusion::at_c;
auto& attr = x3::_attr(ctx);
x3::_val(ctx) = MyDu(at_c<0>(attr), at_c<1>(attr));
};
auto pair = x3::rule<class MyDu_, MyDu>{} = (int_ >> ':' >> int_)[assign];
if (parse(begin(s), end(s), pair, myDu)) {
std::cout << "Parsed: " << myDu.mx << ", " << myDu.my << "\n";
}
}
Prints
Parsed: 11, 22
Oh, fantastic! Many thanks, sehe, you help me solve the problem bothering me for some while.
In fact I can not find document on spirit how to use attr, i only find a doc from "Ruben-Van-Boxem-Parsing-CSS-in-C-with-Boost-Spirit-X3",
_val :A reference to the attribute of the innermost rule invoking _where :the parser Iterator range to the input stream
_attr : A reference to the a˛ribute of the parser
_pass: A reference to a bool flag that can be used to force the parser to fail
could you share some info on these parameters. Many thanks again!
i am using lexical cast in a function for three different variables. Now if a bad_lexical_cast exception occurs i have to set default values respective to each variable. now how to find from which statement the exception is thrown?
You can assign the default values first and then wrap each boost::lexical_cast into a try-catch block.
Or, better, extract a function that does it for you:
#include <boost/lexical_cast.hpp>
#include <iostream>
template<class T, class S>
T lexical_cast_or_default(S s, T default_value) noexcept {
T value;
return boost::conversion::try_lexical_convert(s, value)
? value
: default_value
;
}
int main() {
double a = lexical_cast_or_default("abc", 3.14);
double b = lexical_cast_or_default("123", 3.14);
int c = lexical_cast_or_default<int>("456", 3.14);
std::cout << a << '\n';
std::cout << b << '\n';
std::cout << c << '\n';
}
Outputs:
3.14
123
456
I made a simple example to test boost bind's interaction with derived classes.
I created two subclasses with different getarea functions. I expected
g1 = boost::bind(boost::mem_fn(&Shape::getarea), Rec)
to print the area of Rectangle(10,20) but instead it printed '1'. I get the same when I instead write Rectangle::getarea. It prints the same even when I input other functions eg. member of Rectangle
double sum(double h,double w){return h+w; }
and use
g1 = boost::bind(boost::mem_fn(&Rectangle::sum), Rec,2,3)
Question 1: Why does it return '1'?Is that a default response for error?
My second problem is to do the same of printing g2 but now Rec is replaced by **iter, i.e. an object of some derived class type from a list of objects. Since getarea is a virtual fcn, once I get the above working it should be fine to just write:
g2= boost::bind(boost::mem_fn(& Shape::getarea , &(**iter));
Question 2: However, I was wondering if there is a way to return the classtype of **iter eg. classof(**iter) and then put it in g2 i.e.
g2= boost::bind(boost::mem_fn(& classof(**iter)::getarea , &(**iter));
When I ran g2 by writing Shape::getarea, I got '1' again for all iter.
#include <memory>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <boost/bind.hpp>
using namespace std;
class Shape {
public:
Shape(double h, double w) :height(h), width(w) {};
virtual double getarea() = 0;
double height;
double width; };
class Rectangle: public Shape {
public:
Rectangle(double h, double w): Shape(h,w) {};
double getarea() override { return height*width; } };
class Triangle : public Shape {
public:
Triangle(double h, double w) :Shape(h,w) {};
double getarea() { return height*width*0.5; }};
int main() {
//create objects
Rectangle Rec(10, 20);
Triangle Tri(2, 3);
//create boost bind function
boost::function<double(double, double)> g1;
g1 = boost::bind(boost::mem_fn(&Shape::getarea), Rec);
//print area and g
cout << Rec.getarea()<<" should be equal to " << g1<< '\n';
//create list
vector<shared_ptr<Shape>> Plist;
Plist.push_back(make_shared<Rectangle>(Rec));
Plist.push_back(make_shared<Triangle>(Tri));
//print each element from the vector list
for (auto iter = Plist.begin(); iter != Plist.end(); iter ++ ) {
boost::function<double(double, double)> g2;
g2= boost::bind(boost::mem_fn(& .... , &(**iter));
//where in dots we need Classtype_of_**iter::getarea
cout << (**iter).getarea()<<"should be equal to " << g2<< '\n';
}
}
You... forget to invoke the functions...
for (auto iter = Plist.begin(); iter != Plist.end(); iter++) {
boost::function<double()> g2;
g2 = boost::bind(&Shape::getarea, iter->get());
cout << (*iter)->getarea() << " should be equal to " << g2() << '\n';
}
What you saw what the implicit conversion to bool (http://www.boost.org/doc/libs/1_60_0/doc/html/boost/function.html#idm45507164686720-bb)
Note also I fixed the signature of g1 and g2: Live On Coliru.
Some further improvements (remove the need for the g2 in the loop?):
auto getarea = boost::mem_fn(&Shape::getarea);
for (auto iter = Plist.begin(); iter != Plist.end(); iter++) {
cout << (*iter)->getarea() << " should be equal to " << getarea(**iter) << '\n';
}
Or, indeed in c++11:
for (auto& s : Plist)
cout << s->getarea() << " should be equal to " << getarea(*s) << '\n';
By this time, you'd wonder why you have this accessor when you can just use the member.
This is more a kind of theoretical question. Is it possible in C++11 to combine functions into a new function? For example :
auto f = [](int i){return i * 2;};
auto g = [](int i){return i + 10;};
So this works:
auto c = f(g(20)); // = 60
But I want an object that stores the combination, like
auto c = f(g);
std::cout << c(20) << std::endl; //prints 60
Edit:
Additionally what i want to create is a function a, which you can give a function b and an int n, and which returns the n'th combination of the given function b. For example (not compilable)
template<typename T>
auto combine(T b, int i) -> decltype(T)
{
if (i == 0)
return b;
return combine(b, i - 1);
}
auto c = combine(f, 2); //c = f(f(f(int)))
A first attempt:
template<class First, class Second>
auto compose( Second&& second, First&& first ) }
return [second = std::forward<Second>(second), first=std::forward<First>(first)]
(auto&&...args)->decltype(auto) {
return second( first( decltype(args)(args)... ) );
};
}
template<class A, class B, class...Rest>
auto compose(A&& a, B&& b, Rest&&... rest) {
return compose( compose(std::forward<A>(a), std::forward<B>(b)), std::forward<Rest>(rest)... );
}
template<class A>
std::decay_t<A> compose(A&& a) {
return std::forward<A>(a);
}
in C++14. Now, this isn't perfect, as the pattern doesn't work all that well in C++.
To do this perfectly, we'd have to take a look at compositional programming. Here, functions interact with an abstract stack of arguments. Each function pops some number of arguments off the stack, then pops some number back on.
This would allow you do do this:
compose( print_coord, get_x, get_y )
where get_x and get_y consume nothing but return a coordinate, and print_coord takes two coordinates and prints them.
To emulate this in C++, we need some fancy machinery. Functions will return tuples (or tuple-likes?), and those values will be "pushed onto the argument stack" logically.
Functions will also consume things off this argument stack.
At each invocation, we unpack the current tuple of arguments, find the longest collection that the function can be called with, call it, get its return value, unpack it if it is a tuple, and then stick any such returned values back on the argument stack.
For this more advanced compose to compose with itself, it then needs SFINAE checks, and it needs to be able to take a invokable object and a tuple of arguments and find the right number of arguments to call the invokable object with, plus the left-over arguments.
This is a tricky bit of metaprogramming that I won't do here.
The second part, because I missed it the first time, looks like:
template<class F>
auto function_to_the_power( F&& f, unsigned count ) {
return [f=std::forward<F>(f),count](auto&& x)
-> std::decay_t< decltype( f(decltype(x)(x)) ) >
{
if (count == 0) return decltype(x)(x);
auto r = f(decltype(x)(x));
for (unsigned i = 1; i < count; ++i) {
r = f( std::move(r) );
}
return r;
};
}
This uses no type erasure.
Test code:
auto f = [](int x){ return x*3; };
auto fs = std::make_tuple(
function_to_the_power( f, 0 ),
function_to_the_power( f, 1 ),
function_to_the_power( f, 2 ),
function_to_the_power( f, 3 )
);
std::cout << std::get<0>(fs)(2) << "\n";
std::cout << std::get<1>(fs)(2) << "\n";
std::cout << std::get<2>(fs)(2) << "\n";
std::cout << std::get<3>(fs)(2) << "\n";
prints:
2
6
18
54
You can write something along the lines of:
#include <functional>
#include <iostream>
template<class F>
F compose(F f, F g)
{
return [=](int x) { return f(g(x)); };
}
int main()
{
std::function<int (int)> f = [](int i) { return i * 2; };
std::function<int (int)> g = [](int i) { return i + 10; };
auto c = compose(f, g);
std::cout << c(20) << '\n'; // prints 60
}
The code can be simply extended to cover the second half of the question:
template<class F>
F compose(F f, unsigned n)
{
auto g = f;
for (unsigned i = 0; i < n; ++i)
g = compose(g, f);
return g;
}
int main()
{
std::function<int (int)> h = [](int i) { return i * i; };
auto d = compose(h, 1);
auto e = compose(h, 2);
std::cout << d(3) << "\n" // prints 81
<< e(3) << "\n"; // prints 6561
}
NOTE. Here using std::function. It isn't a lambda but wraps a lambda with a performance cost.
I am learning about lambdas and I don't understand why passing the lambda as a Predicate below is not working.
class Foo2{
public:
bool operator()(const int& n) const {return n%2 == 0;}
};
template<typename Container, typename Predicate>
unsigned int my_count_if(const Container& c, Predicate p)
{
unsigned int cnt = 0;
for(const auto& x : c){
cnt += p(x) ? 1 : 0;
std::cout << "x = " << x << std::endl; // for debug
std::cout << "p(x) = " << p(x) << std::endl; // for debug
}
return cnt;
}
bool test_func(const int& n)
{
return n%2 == 0;
}
int main()
{
std::vector<int> v {1,2,3,4,5,6};
std::cout << my_count_if(v, [] (const int& n) -> bool {n%2 == 0;}); // not working
std::cout << my_count_if(v, test_func) << std::endl; // works
std::cout << my_count_if(v, Foo2()); // works
return 0;
}
The line in which the lambda is used as the predicate does not work. p(x) = 248 for all values of x, but the second version with the function object does work. Am I missing something concerning the passing of lambdas as function arguments? In this post (in the accepted answer) Pass lambda expression to lambda argument c++11 I read that
where there is no state being captured, the language allows for a conversion from the lambda type to a pointer to function with the signature of the operator() (minus the this part), so the lambda >above can be implicitly converted to a pointer
Thank you for any help!