I am trying to make a simple implementation of the std::function
The following code works with function pointers and lambdas which are explicitly converted.
template<typename funct>
class functor {
private:
funct *function;
public:
functor() = default;
functor(funct *func) : function(func) {};
template<typename T>
T operator()(T a, T b){
return function(a, b);
}
};
int add(int a, int b) {
return a + b;
}
int main(int argc, char **argv) {
std::map<std::string, functor<int(int,int)>> maps = { {"+", add} };
maps.insert({ "%", {[](int i, int j)->int { return i * j; } } } );
auto temp = maps["%"](5,6);
std::cout << temp << std::endl;
system("PAUSE");
return 0;
}
I want to know why lambdas don't work with implicit conversion.
maps.insert({ "%", [](int i, int j)->int { return i * j; } } );
The above code doesn't work but the following does:
maps.insert({ "%", {[](int i, int j)->int { return i * j; } } } );
but the std::function works with {} and without.
As #KerrekSB mentioned in the comments, just give your functor a templated constructor like this:
template<class F>
functor(F f) : function(f) {}
Now you can omit the braces when initializing the map:
#include <map>
#include <iostream>
template<typename funct>
class functor {
private:
funct *function;
public:
functor() = default;
template<class F>
functor(F f) : function(f) {}
template<typename T>
T operator()(T a, T b){
return function(a, b);
}
};
int add(int a, int b) {
return a + b;
}
int main(int argc, char **argv) {
std::map<std::string, functor<int(int,int)>> maps = { {"+", add} };
maps.insert({ "%", [](int i, int j)->int { return i * j; } } );
auto temp = maps["%"](5,6);
std::cout << temp << std::endl;
}
Live Example
Related
How can I achieve that CoroutineManager::Routine() calls Operator::Worker() ?
Worker() must be called by Routine() in this test scenario.
So the question is whether how C++ handle the context. The Routine() method must not implemented by the Operator class itself.
template <class T>
class CoroutineManager {
private:
T var;
int _a, _b;
public:
CoroutineManager(int a, int b);
T Worker();
void Routine();
};
template <class T>
CoroutineManager<T>::CoroutineManager(int a, int b) {
this->_a = a;
this->_b = b;
}
template <class T>
T CoroutineManager<T>::Worker() {
std::cout << "wrong method" << std::endl;
return var;
}
template <class T>
void CoroutineManager<T>::Routine() {
std::cout << this->Worker() << std::endl;
}
class Operator : public CoroutineManager<double> {
using CoroutineManager::CoroutineManager;
public:
Operator(int a, int b) : CoroutineManager(a,b) {};
virtual double Worker();
};
double Operator::Worker() {
return 3.141;
}
// MARK: -
int main(int argc, const char * argv[]) {
Operator *op = new Operator(3,4);
op->Routine();
return 0;
}
I've changed the code to fulfill my requirements, but maybe there are exists more straight forward solutions(?). It's only about Worker and Worker2, two different methods in two objects which can be called by the derived Routine method without the boundaries of inheritance context:
// MARK: -
template <typename T, typename V>
class CoroutineManager {
private:
V _a, _b;
V (T::*workerPtr)();
T *cm;
public:
CoroutineManager(V a, V b) {
this->_a = a;
this->_b = b;
}
void Routine() {
std::cout << (*cm.*workerPtr)() << std::endl;
}
void SetWorker(T *cm, V (T::*ptr)()) {
this->workerPtr = ptr;
this->cm = cm;
}
V getA() {
return this->_a;
}
V getB() {
return this->_b;
}
};
// MARK: -
class Operator : public CoroutineManager<Operator,int> {
private:
int xx;
public:
Operator(int a, int b) : CoroutineManager(a,b) {
this->xx = a*2 + b*2;
};
int Worker();
};
int Operator::Worker() {
return getA() * getB() + this->xx;
}
// MARK: -
class Operator2 : public CoroutineManager<Operator2,double> {
public:
Operator2(double a, double b) : CoroutineManager(a,b) {};
double Worker2();
};
double Operator2::Worker2() {
return getA() + getB();
}
// MARK: -
int main(int argc, const char * argv[]) {
Operator *op = new Operator(4,4);
int (Operator::*workerPtr)() = &Operator::Worker;
op->SetWorker(op, workerPtr);
op->Routine();
Operator2 *op2 = new Operator2(3.14,2.78);
double (Operator2::*workerPtr2)() = &Operator2::Worker2;
op2->SetWorker(op2, workerPtr2);
op2->Routine();
return 0;
}
Output:
32
5.92
Program ended with exit code: 0
I want to create a functor class that can accept other callable objects.
For example I tried the following:
#include <iostream>
template<class RetType,class ObjType,class... Params>
struct Functor {
using FuncSig = RetType (ObjType::*)(Params...);
FuncSig funcptr;
ObjType *obj;
RetType operator()(Params... params) {
return (obj->*funcptr)(params...);
}
};
class command {
int x;
char *ch;
public:
void operator()(int a,char *x) {
// some task
std::cout << "task1 done!" << std::endl;
}
};
int main() {
Functor<void,command,int,char *> f;
command c;
f.funcptr = &command::operator();
f.obj = &c;
char x[] = {'a','b'};
f(100,x);
}
This works. But when I want to work with normal function callable object, I need to create a different Functor class:
#include <iostream>
template<class RetType,class ObjType,class... Params>
struct Functor {
using FuncSig = RetType (ObjType::*)(Params...);
FuncSig funcptr;
ObjType *obj;
RetType operator()(Params... params) {
return (obj->*funcptr)(params...);
}
};
class command {
int x;
char *ch;
public:
void operator()(int a,char *x) {
// some task
std::cout << "task1 done!" << std::endl;
}
};
template<class RetType,class... Params>
struct Functor2 {
using FuncSig = RetType (*)(Params...);
FuncSig funcptr;
RetType operator()(Params... params) {
return (*funcptr)(params...);
}
};
void normalFunction(double x) {
std::cout << "task2 done!" << std::endl;
}
int main() {
Functor<void,command,int,char *> f;
command c;
f.funcptr = &command::operator();
f.obj = &c;
char x[] = {'a','b'};
f(100,x);
//........
Functor2<void,double> g;
g.funcptr = normalFunction;
g(1.2);
}
How to create a generic Functor class that can accept any callable objects (class with operator() or normal function) with the following acceptable syntax.
Functor<ReturnType,int,double,more params ..> F(a_callable_objects);
F(arguments);
With std::function, you might do:
command c;
std::function<void(int, char *)> f = [&](int n, char* buf){ return c(n, buf); };
char x[] = {'a', 'b'};
f(100, x);
//...
std::function<void(double)> g = normalFunction;
g(1.2);
Demo
Is there anyways to fusion::for_each() to iterate through a1 and a2 in a BOOST_FUSION_ADAPT_ADT or BOOST_FUSION_ADAPT_ASSOC_ADT, just like if adapted using BOOST_FUSION_ADAPT_STRUCT?
class A
{
private:
int a1_;
double a2_;
public:
void set_a1(int v) { a1_ = v; }
int get_a1() const { return a1_; }
void set_a2(double v) { a2_ = v; }
double get_a2() const { return a2_; }
};
BOOST_FUSION_ADAPT_ASSOC_ADT(
A,
(int, int, obj.get_a1(), obj.set_a1(val) )
(double, double, obj.get_a2(), obj.set_a2(val) )
)
struct Print
{
template <typename T>
void operator()( T& t ) const
{
// T is of type adt_attribute_proxy
// cout << ??
// would like to print a1 and a2 value
}
};
int main()
{
A a;
boost::fusion::for_each( a, Print() );
}
adt_attribute_proxy provides method get to access attribute value.
struct Print
{
template <typename T>
void operator()(T& t) const
{
std::cout << t.get();
}
};
P.S. There are errors in you sample BOOST_FUSION_ADAPT_ASSOC_ADT macro. Each element should be declared with 5 params (attribute_typeN, attribute_const_typeN, get_exprN, set_exprN, key_typeN) Maybe you mix up BOOST_FUSION_ADAPT_ASSOC_ADT with BOOST_FUSION_ADAPT_ADT?
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
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});
// ^ ^