Retrieve value from object member through std::bind - c++

I'm wondering if it's possible to have a bind expression not return an object, but an member of the object. Here is the idea (I want to get val directly from B):
struct A
{
A(float _val) : val(_val) {}
float val;
};
struct B
{
B(float _val) : a(_val) {}
A a;
};
int main()
{
B b{ 2.0f };
auto get_a_from_b = std::bind(&B::a, std::placeholders::_1);
const A& a = get_a_from_b(b); // ok
auto get_val_from_a = std::bind(&A::val, std::placeholders::_1);
float val = get_val_from_a(a); // ok, val = 2.0f
// error
auto get_val_from_b = std::bind(&B::a::val, std::placeholders::_1);
auto x = get_val_from_b(b);
}
In particular, can the concept of B::a::val work or is it conceptually wrong? (I am aware that this can be achieved with a lambda, but that's not the question.)
Thanks!

Ok as liliscent said, it can't be done directly. You may, however, link it together like so:
int val = std::mem_fn(&A::val)(std::mem_fn(&B::a)(b));
(mem_fn is the better function for this endeavour).
This can be made more compact with its own function:
#include <functional>
#include <array>
#include <vector>
#include <iostream>
struct A
{
A(int _val = 0) : val(_val) {}
int val;
};
struct B
{
B(int _val = 0) : a(_val) {}
A a;
};
template<typename Elem, typename Head, typename... Tail>
constexpr decltype(auto) getElement(const Elem& _elem, Head&& _head, Tail&&... _tail)
{
auto fn = std::mem_fn(std::forward<Head>(_head));
if constexpr(sizeof...(_tail) == 0)
{
return fn(_elem);
}
else
{
return getElement(fn(_elem), std::forward<Tail>(_tail)...);
}
}
int main()
{
B b{ 7 };
int i = getElement(b, &B::a, &A::i); // get the a from B first, then get the val from that a
int j = getElement(b.a, &A::i);
return 0;
}
But the more you stack if up, the more the brevity advantage compared to the lambda vanishes. Oh well.

Related

Operation overloading in composite design pattern in C++

Suppose I have this code all set up:
class Function
{
public:
virtual double eval(double x) const =0;
};
class Polynomial : public Function
{
private:
std::vector<double> coefficients;
public:
// ...
};
class CompositeFunction : public Function
{
private:
char operation;
Function* left;
Function* right;
public:
// ...
};
CompositeFunction operator+(Function& f, Function& g) {
return CompositeFunction('+',&f,&g);
}
Now, I'm trying to do the following thing:
CompositeFunction f = Polynomial({1,2}) + Polynomial({3,2});
printf("%lf\n",f.eval(1));
I don't get any compilation errors but when I try to eval f, Valgrind tells me I'm acessing bad data. I always get the correct answer but this is bugging me off.
I have tried to stop using stack-allocated arguments but I can't overload any pointer operation.
Is there any pointer-less way or friendly for the users of these classes?
It's because f has references to two temporary objects.
Expand it out to make it more obvious:
CompositeFunction f = operator+( Polynomial({1,2}), Polynomial({3,2}) );
f now holds references to the temporaries created by Polynomial({1,2}) and Polynomial({3,2}).
You might want to consider using std::function<double(double)> objects and lambdas, something like this:
#include <iostream>
#include <functional>
#include <vector>
typedef std::function<double(double)> Function;
Function polynomial(std::vector<double> const &coefficients) {
return [coefficients](double x) {
return x * coefficients[0]; // dummy evaluation
};
}
Function add(Function f1, Function f2) {
return [f1, f2](double x) { return f1(x) + f2(x); };
}
int main() {
Function f = add(polynomial({3,4}), polynomial({1,2}));
std::cout << f(3.3) << std::endl;
}
Here it is with std::shared_ptr:
#include <iostream>
#include <functional>
#include <memory>
#include <vector>
class Function
{
public:
virtual double eval(double x) const = 0;
virtual double derivative(double x) const = 0;
virtual ~Function() {}
};
typedef std::shared_ptr<Function> FunctionPtr;
class Polynomial : public Function
{
private:
std::vector<double> coefficients;
public:
// ...
Polynomial(std::vector<double> c) : coefficients(c) {}
};
class CompositeFunction : public Function
{
private:
char operation;
FunctionPtr left;
FunctionPtr right;
public:
// ...
CompositeFunction(FunctionPtr l, FunctionPtr r) : operation('+'), left(l), right(r) {}
};
FunctionPtr operator+(FunctionPtr f, FunctionPtr g) {
return std::make_shared<CompositeFunction>(f, g);
}
int main() {
auto p1 = std::make_shared<Polynomial>(std::vector<double>{1.0, 2.0});
auto p2 = std::make_shared<Polynomial>(std::vector<double>{3.0, 4.0});
auto f = std::make_shared<CompositeFunction>(p1, p2);
auto f2 = p1 + p2;
std::cout << f2->eval(3.3) << std::endl;
std::cout << f2->derivative(3.3) << std::endl;
}

How to generate a std::get like function for my class?

For example, I have a class
struct A {int a; bool b;};
And I want to generate a template function to get its elements (like the std::get to get a tuple element)
template<unsigned i, class T>
auto Get(T& t);
template<>
int& Get<0, A>(A& a)
{
return a.a;
}
template<>
bool& Get<1, A>(A& a)
{
return a.b;
}
int main()
{
A a;
Get<0>(a) = 10;
Get<1>(a) = true;
return 0;
}
The above code doesn't work. The challenge is that I don't know the returned type of Get for arbitrary class. Any way to implement it? Thanks.
Assuming you wouldn't mind making this in a "manual manner" you can do this really simply.
#include <tuple>
struct A {
int a; bool b;
};
template<size_t N>
auto get(A& a) -> decltype(std::get<N>(std::tie(a.a, a.b))) {
return std::get<N>(std::tie(a.a, a.b));
}
#include <iostream>
int main() {
A a;
get<0>(a) = 10;
get<1>(a) = true;
std::cout << a.a << '\n' << a.b;
}
Output:
10
1

Is there a standalone implementation of std::function?

I'm working on an embedded system, so code size is an issue. Using the standard library ups my binary size by about 60k, from 40k to 100k. I'd like to use std::function, but I can't justify it for 60k. Is there a standalone implementation that I can use, or something similar? I'm using it to implicitly cast lambdas in member functions with bound variables in c++ 11.
Here is simple implementation of std::function-like class template without inclusion of any headers. You can customize the behavior as you wish(like move/forward, empty call response, etc):
live_demo
// Scroll down for example of usage
namespace bicycle
{
template<typename Result,typename ...Args>
struct abstract_function
{
virtual Result operator()(Args... args)=0;
virtual abstract_function *clone() const =0;
virtual ~abstract_function() = default;
};
template<typename Func,typename Result,typename ...Args>
class concrete_function: public abstract_function<Result,Args...>
{
Func f;
public:
concrete_function(const Func &x)
: f(x)
{}
Result operator()(Args... args) override
{
return f(args...);
}
concrete_function *clone() const override
{
return new concrete_function{f};
}
};
template<typename Func>
struct func_filter
{
typedef Func type;
};
template<typename Result,typename ...Args>
struct func_filter<Result(Args...)>
{
typedef Result (*type)(Args...);
};
template<typename signature>
class function;
template<typename Result,typename ...Args>
class function<Result(Args...)>
{
abstract_function<Result,Args...> *f;
public:
function()
: f(nullptr)
{}
template<typename Func> function(const Func &x)
: f(new concrete_function<typename func_filter<Func>::type,Result,Args...>(x))
{}
function(const function &rhs)
: f(rhs.f ? rhs.f->clone() : nullptr)
{}
function &operator=(const function &rhs)
{
if( (&rhs != this ) && (rhs.f) )
{
auto *temp = rhs.f->clone();
delete f;
f = temp;
}
return *this;
}
template<typename Func> function &operator=(const Func &x)
{
auto *temp = new concrete_function<typename func_filter<Func>::type,Result,Args...>(x);
delete f;
f = temp;
return *this;
}
Result operator()(Args... args)
{
if(f)
return (*f)(args...);
else
return Result{};
}
~function()
{
delete f;
}
};
}
// ___________________[ Example of usage ]___________________ //
int func1(double)
{
return 1;
}
struct Functor2
{
int operator()(double)
{
return 2;
}
};
double func3(bool,int)
{
return 3.0;
}
struct Functor4
{
double operator()(bool,int)
{
return 4.0;
}
};
int main()
{
int res = 10;
{
bicycle::function<int(double)> f{func1};
res -= f(1.0);
f = Functor2{};
res -= f(2.0);
}
{
bicycle::function<double(bool,int)> f1;
f1 = func3;
bicycle::function<double(bool,int)> f2{f1};
res -= f2(true,1);
f1 = Functor4{};
f2 = f1;
res -= f2(false,2);
}
return res;
}
The 60k came from exception handling being added by the compiler, because exceptions were required for std::function. std::function only throws one exception, "bad_function_call". So I removed the code that threw the exception, now it seg faults if an empty function is called, and I saved myself 60k.

Variable user-defined parameter list in C++?

I'm looking for a simple way to create a user multi-parameter receiving function,
Here's some pseudo code
#include <iostream>
struct A {
int m_num;
};
void function(A* a, ...)
{
/* Pseudo-Code here */
for each parameter do
print a->m_num
end
}
int main()
{
A *a = new A();
A *b = new A();
A *c = new A();
a->m_num = 1;
b->m_num = 10;
c->m_num = 100;
function(a,b,c);
// delete everything
return 0;
}
I can't really use boost here, so if it's possible with standard C++ ( STL Allowed ), it would be great.
EDIT: The function parameters are heterogeneous
Old school plain C variadic arguments:
#include <cstdio>
#include <stdarg.h>
struct A {
A () : m_num (0) {}
A (int v) : m_num (v) {}
int m_num;
};
void function (A *a, ...)
{
va_list ap;
A *p = a;
va_start (ap, a);
while (p != NULL)
{
printf ("%d\n", p->m_num);
p = va_arg (ap, A*);
}
va_end (ap);
}
int main()
{
A a (1), b (10), c (100);
function (&a, &b, &c, NULL);
}
Another solution if arguments are of the same type (which is your case):
#include <cstdio>
struct A {
A () : m_num (0) {}
A (int v) : m_num (v) {}
int m_num;
};
void function (A *p, A *endp)
{
while (p != endp)
{
printf ("%d\n", p->m_num);
++p;
}
}
int main()
{
A a[3];
a[0].m_num = 1;
a[1].m_num = 10;
a[2].m_num = 100;
function (a, a + sizeof (a) / sizeof(a[0]));
}
Or even more C++-style, with iterators:
#include <cstdio>
#include <vector>
#include <list>
struct A {
A () : m_num (0) {}
A (int v) : m_num (v) {}
int m_num;
};
template <typename T>
void function (T p, T endp)
{
while (p != endp)
{
printf ("%d\n", p->m_num);
++p;
}
}
int main()
{
A a[3];
a[0].m_num = 1;
a[1].m_num = 10;
a[2].m_num = 100;
function (a, a + sizeof (a) / sizeof(a[0]));
std::vector<A> av (3);
av[0].m_num = 1;
av[1].m_num = 10;
av[2].m_num = 100;
function (av.begin (), av.end ());
std::list<A> al;
al.push_back (A (1));
al.push_back (A (10));
al.push_back (A (100));
function (al.begin (), al.end ());
}
The most straightforward way is to put your parameters into a std::vector. If they're non-homogeneous you can use a vector of boost::any or boost::variant.
Alternately design your interface like streams and use an insertion like operator/function that operators on one parameter at a time.
It would look something like this, alternately using a friend free-function.
struct A
{
int m_num;
};
struct printer
{
function& operator<<(A* a)
{
/* Pseudo-Code here */
print a->m_num
return *this;
}
};
int main()
{
A *a = new A();
A *b = new A();
A *c = new A();
a->m_num = 1;
b->m_num = 10;
c->m_num = 100;
printer function;
function << a << b << c;
// delete everything
return 0;
}
If every parameter going into function is an A, I'd do it with an array of A's, as in:
int main() {
A *abc[3];
for (int i=0;i<3;i++)
abc[i]=new A();
abc[0]->m_num=1;
abc[1]->m_num=10;
abc[2]->m_num=100;
function(abc,3);
}
void function(A *vals[],int count) {
for (int i=0;i<count;i++)
print vals[i]->m_num;
}
If you have a compiler recent enough to ship with std::tuple<> or std::tr1::tuple<>, you can do the following:
#include <cstddef>
#include <tuple>
#include <iostream>
struct A
{
int m_num;
};
template<typename T>
class function_impl
{
template<std::size_t N>
static void impl(T const& tup)
{
std::cout << std::get<N>(tup)->m_num << '\n';
}
template<std::size_t N>
struct recurse_helper
{
static void invoke(T const& tup)
{
function_impl<T>::template impl<N>(tup);
recurse_helper<N + 1u>::invoke(tup);
}
};
template<>
struct recurse_helper<std::tuple_size<T>::value>
{
static void invoke(T const&) { }
};
public:
static void invoke(T const& tup)
{
recurse_helper<0u>::invoke(tup);
}
};
template<typename T>
void function(T const& tup)
{
function_impl<T>::invoke(tup);
}
int main()
{
A* a = new A();
a->m_num = 1;
A* b = new A();
b->m_num = 10;
A* c = new A();
c->m_num = 100;
function(std::tie(a, b, c));
delete c;
delete b;
delete a;
}
Note that function actually takes a singular argument, a tuple<>, rather than multiple arguments. But, unlike any varargs-based solution, this is completely type-safe.
Also note that the implementation here would be much simpler if you could use Boost.Fusion...
As a supplement.
In C++0x, you could use variadic-template to implement your function recursively:
// Just to make the compiler happy.
template <typename T>
void function(T a) = delete;
// Base case
template <>
void function(A* a) {
printf("%d\n", a->m_num);
}
// Recursion
template <typename T, typename... Args>
void function(T a, Args... args) {
function(a);
function(args...);
}
But this will generate N functions if it accepts N parameters. Alternatively, you could use an initializer_list:
void function(std::initializer_list<A*> args) {
for (auto cit = args.begin(); cit != args.end(); ++ cit)
printf("%d\n", (*cit)->m_num);
}
but you need to call function as
function({a,b,c});
// ^ ^

"Automatic" class proxy in C++

I need to allow the user to change members of two data structures of the same type at the same time. For example:
struct Foo { int a, b; }
Foo a1 = {1,2}, a2 = {3,4};
dual(a1,a2)->a = 5;
// Now a1 = {5,2} and a2 = {5,2}
I have a class that works and that change first a1 and then copy a1 into a2. This is fine as long as:
the class copied is small
the user doesn't mind about everything being copied, not only the part modified.
Is there a way to obtain this behavior:
dual(a1,a2)->a = 5;
// Now a1 = {5,2} and a2 = {5,4}
I am opened to alternative syntax, but they should stay simple, and I would like to avoid things like:
set_members(a1, a2, &Foo::a, 5);
members(a1, a2, &Foo::a) = 5;
or anything involving specifying explictely &Foo::
[Edit]
I should be more precise. The point is to work with a graph library. The library works on directed graph, but usage dictate that given two vertices, v1 and v2, if there is an edge v1->v2, then there will be an edge v2->v1. And these two edges have, very often (but not always) the same properties. So the current implementation now allows:
G.edge(v1,v2)->b = 5; // Only v1->v2 is modified
G.arc(v1,v2)->a = 10;
// Now G.edge(v2,v1) is set to G.edge(v1,v2) after the modification a = 10 (i.e. b = 5 too)
And I would like the notation to imply that only a is modified.
Relatively simple solution with Boost.Lambda:
#include <boost/lambda/lambda.hpp>
using namespace boost::lambda;
template<typename T, typename U, typename V>
void dual(const T& functor, U& a1, V& a2)
{
functor(a1);
functor(a2);
}
struct Foo
{
int a;
};
struct Bar
{
char a;
};
int main()
{
Foo a1;
Bar a2;
dual(_1 = 5, a1.a, a2.a);
}
Extending dual() with variadic templates / Boost.Preprocessor shenanigans is left as an exercise to the reader.
//to get the desired syntax
template<class T>
class SetPropertyProxy
{
public:
SetPropertyProxy(T& _v1, T& _v2)
: a(_v1, _v2) {}
class A_Property_Proxy
{
public:
A_Property_Proxy(T& _v1, T& _v2): v1(_v1), v2(_v2) {}
A_Property_Proxy& operator = (T::A_Property_Type val)
{
v1.a = val;
v2.a = val;
return *this;
}
private:
T& v1;
T& v2;
}
//public member "a"
A_Property_Proxy a;
};
//helper function
template<class T>
SetPropertyProxy<T> dual(T& a , T& b)
{ return SetPropertyProxy<T>(a,b); }
//usage
dual(a,b).a = 5; //calls A_Property_Proxy::operator =
It can be improved further making A_Property_Proxy class reusable by parameterizing by property type and taking references to properties instead of references to property containers (edges in this case)
template<class U>
class Property_Proxy
{
public:
Property_Proxy(U& _v1prop, U& _v2prop): v1prop(_v1prop), v2prop(_v2prop) {}
Property_Proxy& operator = (U val)
{
v1prop = val;
v2prop = val;
return *this;
}
private:
U& v1prop;
U& v2prop;
}
Edit (putting this here because comments don't have formatting)
So are you saying that your current code has lots of this:
G.edge(v3,v4)->a = 2;
G.edge(v3,v4)->b = 2;
G.edge(v4,v5)->a = 6;
G.edge(v4,v5)->b = 6;
And a very little bit of this:
G.edge(v5,v6)->a = 4;
G.edge(v5,v6)->b = 7;
And your goals are [1] make it easier to spot those special cases [2] less verbose code?
----- original answer, may be irrelevant now -----
Here's a general idea, there are lots of possible improvements:
class MagicBag
{
private:
// you could make the whole class a template
// instead of hard-coding Foo..
vector<Foo *> m_vec;
public:
// store references to the items
void Add(Foo *f) { m_vec->push_back(f); }
// you can do overloads instead of these setters...
void set_a(int val) {
for (vector<Foo>::iterator i = m_vec.start(); i != m_vec.end(); ++i)
(*i)->a = val;
}
void set_b(int val) {
for (vector<Foo>::iterator i = m_vec.start(); i != m_vec.end(); ++i)
(*i)->b = val;
}
}
Usage:
Foo a1 = {1,2}, a2 = {3,4};
MagicBag mb;
mb.Add(&a1);
mb.Add(&a2);
mb.set_a(5); // now a1.a = 5 and a2.a = 5
// etc.
This is easier semantically in languages which support Properties, such as C#. There the final syntax would be:
mb.a = 5;
By introducing an abuse of templates I can get most of the desired syntax. This compiles and works, but no guarantees are made about it. It requires adding some macros the struct to be used and requires use of set_* instead of direct assignment.
#include <iostream>
#define PROPERTY_MAP(ClassName) \
struct hidden_Mapper { \
ClassName * m_d1; \
ClassName * m_d2; \
hidden_Mapper(Data * d1, Data * d2) : \
m_d1(d1), m_d2(d2) {}
#define DECLARE_PROPERTY(name)\
template <typename ValueType> \
void set_##name(const ValueType & value) \
{ m_d1->name = value; m_d2->name = value; } \
#define END_PROPERTY_MAP };
template<typename ClassType>
typename ClassType::hidden_Mapper dual(ClassType & d1, ClassType & d2)
{
return typename ClassType::hidden_Mapper(&d1, &d2);
}
struct Data
{
int a;
float b;
PROPERTY_MAP(Data)
DECLARE_PROPERTY(a)
DECLARE_PROPERTY(b);
END_PROPERTY_MAP
};
int main()
{
Data d1, d2;
dual(d1, d2).set_a(5);
dual(d1, d2).set_b(5.7);
std::cout << d1.a << d2.a << d1.b << d2.b <<std::endl;
}
struct proxy {
struct column {
column(T &a, T &b);
column& operator=(T);
T &a, &b;
};
proxy(U &A, U &B);
column operator[](int i) { return column(A[i], B[i]; }
U &A, &B;
};
proxy(A, B)[0] = 5;
// or you could be evil, overload ",", and get this syntax
(A, B)[0] = 5;
or some sort of variation