This was my original code
#include "stdafx.h"
#include <string>
#include <list>
#include <algorithm>
using namespace std;
class testing
{
public:
int value;
testing(int v)
{
value = v;
}
int getval()
{
return(value);
}
};
void func(testing& ob)
{
printf("The value is %d\n", ob.value);
}
int _tmain(int argc, _TCHAR* argv[])
{
std::list<testing> testvar[3];
testing t1(0);
testing t2(1);
testing t3(3);
testvar[0].push_back(t1);
testvar[0].push_back(t2);
testvar[0].push_back(t3);
std::for_each(testvar[0].begin(), testvar[0].end(), func);
printf("Reached End");
getchar();
return 0;
}
I modified it to make func a member function and got weird compile errors, I searched online and someone had told use bind1st, bind2nd
#include "stdafx.h"
#include <string>
#include <list>
#include <algorithm>
using namespace std;
class testing
{
public:
int value;
testing(int v)
{
value = v;
}
int getval()
{
return(value);
}
};
class testing2
{
public:
std::list<testing> testvar[3];
void func(testing& ob)
{
printf("The value is %d\n", ob.value);
}
void driver()
{
std::for_each(testvar[0].begin(), testvar[0].end(), func);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
testing2 testob;
testob.driver();
printf("Reached End");
getchar();
return 0;
}
So I modified the driver function to this
void driver()
{
std::for_each(testvar[0].begin(), testvar[0].end(), std::bind1st(std::mem_fun(&testing2::func), this));
}
I still get some weird compile erros, could someone please expain why we need to call a member function is such weird way..? and how does bind1st help..?
Use std::bind
std::for_each(testvar[0].begin(), testvar[0].end(), std::bind(&testing2::func, this, std::placeholders::_1));
Or use std::bind/lambdas
std::for_each(testvar[0].begin(), testvar[0].end(), [this](testing& ob) { func(ob); });
Full:
#include <string>
#include <list>
#include <algorithm>
using namespace std;
struct testing {
int value;
testing(int v) { value = v; }
int getval() { return(value); }
};
struct testing2 {
std::list<testing> testvar[3];
void func(testing& ob) {
printf("The value is %d\n", ob.value);
}
void driver() {
auto f = std::bind(&testing2::func, this, std::placeholders::_1);
std::for_each(testvar[0].begin(), testvar[0].end(), f);
std::for_each(testvar[0].begin(), testvar[0].end(), [this](testing& ob) { func(ob); });
}
};
int main() {
testing2 testob;
testob.driver();
printf("Reached End");
}
You can also use std::mem_fn for cleaner syntax like this:
std::for_each(testvar[0].begin(), testvar[0].end(), std::mem_fn(&testing::func));
Complete code:
#include <stdio.h>
#include <bits/stdc++.h>
class testing
{
public:
testing(int v) : value(v) {}
int getval() {
return(value);
}
void func()
{
printf("The value is %d\n", value);
}
private:
int value;
};
int main() {
std::list<testing> testvar[3];
testing t1(0);
testing t2(1);
testing t3(3);
testvar[0].push_back(t1);
testvar[0].push_back(t2);
testvar[0].push_back(t3);
std::for_each(testvar[0].begin(), testvar[0].end(), std::mem_fn(&testing::func));
return 0;
}
Related
can someone please explain why the following code compilation fails with message "passing ‘const apple’ as ‘this’ argument of ‘int apple::foo()’ discards qualifiers", and how to resolve it.
#include <cstdlib>
#include <iostream>
#include <string>
#include <map>
using namespace std;
/*
*
*/
class apple{
private:
int a,b,c,d;
public:
int foo(){
return a+b+c+d;
}
};
class ball{
private:
map<apple,string> mp;
public:
void foo2(){
for(map<apple,string>::iterator it = mp.begin();it!=mp.end();++it){
cout<<it->first.foo()<<endl;
}
}
}
int main(int argc, char** argv) {
return 0;
}
Works for me: (added const at the end of foo() and ; on end of ball class). Class apple is a Key in std::map which is declared as const: typedef pair value_type; so accessing key should be also declared as const.
#include <map>
#include <iostream>
using namespace std;
class apple{
private:
int a,b,c,d;
public:
int foo() const {
return a+b+c+d;
}
};
class ball{
private:
map<apple,string> mp;
public:
void foo2(){
for(map<apple,string>::iterator it = mp.begin();it!=mp.end();++it){
cout<<it->first.foo()<<endl;
}
}
};
int main(int argc, char** argv) {
return 0;
}
I have this class:
boer.h
#pragma once
#include <functional>
#include <iostream>
class boer
{
private:
std::function<void(int id_)> someFun;
public:
boer();
~boer();
void setSomeFun(std::function<void(int id_)> someFun_);
void getSomeFun();
};
boer.cpp
#include "boer.h"
boer::boer() { }
boer::~boer() { }
void boer::setSomeFun(std::function<void(int id_)> someFun_)
{
someFun = someFun_;
}
void boer::getSomeFun()
{
someFun(12345);
}
And this class:
aircraft.h
#pragma once
#include <functional>
#include <iostream>
#include "boer.h"
class aircraft
{
private:
boer Boer;
public:
aircraft();
~aircraft();
void source_forSomeFun(int id_);
};
aircraft.cpp
#include "aircraft.h"
aircraft::aircraft() { }
aircraft::~aircraft() { }
void aircraft::source_forSomeFun(int lol_)
{
std::cout << "AMAZING!!!" << std::endl;
}
And I need to connect void source_forSomeFun(int id_); in aicraft with std::function<void(int id_)> someFun; in boer. How can I do this? Maybe there is another way, but i think this method is the most preferable.
int main()
{
aircraft Aircraft;
boer Boer;
Boer.setSomeFun(???); // here
Boer.getSomeFun();
int i;
std::cin >> i;
return 0;
}
Boer.setSomeFun([&](int v){aircraft.source_forSomeFun(v);});
Use a lambda.
#include <iostream>
#include <algorithm>
#include <numeric>
#include <vector>
using namespace std;
class C
{
public:
vector<int> CSort();
bool Func(int x, int y);
private:
vector<int> data;
};
vector<int> C::CSort()
{
vector<int> result(data.size(), 0);
iota(result.begin(), result.end(), 0);
sort(result.begin(), result.end(), Func);
return result;
}
bool C::Func(int x, int y)
{
return (data[x] > data[y]);
}
In my class C defined as above, I would like to get an order vector of data with std::sort using the member function Func. The result was an error
'C::Func': non-standard syntax; use '&' to create a pointer to member
I believe this has something to do with Why doesn't reference-to-member exist in C++.
However, I cannot come up a proper way to reference this function in std::sort. How can I implement it correctly?
A lambda will work:
#include <iostream>
#include <algorithm>
#include <numeric>
#include <vector>
using namespace std;
class C
{
public:
vector<int> CSort();
bool Func(int x, int y);
private:
vector<int> data;
};
vector<int> C::CSort()
{
vector<int> result(data.size(), 0);
iota(data.begin(), data.end(), 0);
sort(data.begin(), data.end(), [this](auto& l, auto& r) {return Func(l, r); });
return result;
}
bool C::Func(int x, int y)
{
return (data[x] > data[y]);
}
int main()
{
C c;
}
or bind:
#include <iostream>
#include <algorithm>
#include <numeric>
#include <vector>
#include <functional>
using namespace std;
class C
{
public:
vector<int> CSort();
bool Func(int x, int y);
private:
vector<int> data;
};
vector<int> C::CSort()
{
vector<int> result(data.size(), 0);
iota(data.begin(), data.end(), 0);
sort(data.begin(), data.end(), std::bind(&C::Func,this,std::placeholders::_1,std::placeholders::_2));
return result;
}
bool C::Func(int x, int y)
{
return (data[x] > data[y]);
}
int main()
{
C c;
}
You've got a couple of options:
If you don't have access to C++11 you can go old school and implement your own comparator that preserves state:
class C
{
friend struct MyComp;
public:
vector<int> CSort();
private:
vector<int> data;
};
struct MyComp
{
C* data;
MyComp(C* data) : data(data) {}
bool operator()(int x, int y)
{
return data->data[x] > data->data[y];
}
};
vector<int> C::CSort()
{
vector<int> result(data.size(), 0);
iota(data.begin(), data.end(), 0);
sort(data.begin(), data.end(), MyComp(this));
return result;
}
However, if you do, you can just use a lambda:
vector<int> C::CSort()
{
vector<int> result(data.size(), 0);
iota(data.begin(), data.end(), 0);
sort(data.begin(), data.end(), [this] (int x, int y) {
return (data[x] > data[y]);
});
return result;
}
Quick and dirty way: Move Func outside the class.
#include <iostream>
#include <algorithm>
#include <numeric>
#include <vector>
using namespace std;
class C
{
public:
vector<int> CSort();
private:
vector<int> data;
};
bool Func(int x, int y) {
return x > y;
}
vector<int> C::CSort()
{
vector<int> result(data.size(), 0);
// iota(data.begin(), data.end(), 0);
sort(data.begin(), data.end(), Func);
return result;
}
I am trying to use boost::function with instance methods using the following example
class someclass
{
public:
int DoIt(float f, std::string s1)
{
return 0;
}
int test(boost::function<int(float, std::string)> funct)
{
//Funct should be pointing to DoIt method here
funct(12,"SomeStringToPass");
}
void caller()
{
test(DoIt); //Error : 'someclass::DoIt': function call missing argument list; use '&someclass::DoIt' to create a pointer to member
}
};
Any suggestion on how I could resolve this issue ?
You should use boost::bind:
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <string>
#include <iostream>
using namespace std;
class someclass
{
public:
int DoIt(float f, std::string s1)
{
return 0;
}
int test(boost::function<int(float, std::string)> funct)
{
return funct(5.0, "hello");
}
void caller()
{
cout << test(boost::bind(&someclass::DoIt, this, _1, _2)) << endl;
}
};
int main() {
someclass s;
s.caller();
}
Below is my code
#include "stdafx.h"
#include <string.h>
#include <iostream.h>
using namespace std;
class ToDoCommands
{
public:
void getCommand(string);
};
void ToDoCommands::getCommand(string command)
{
cout<<command; //here i get ping
void (*CommandToCall)(void);
CommandToCall = command; // error here i want something like
// CommandToCall = ping
CommandToCall();
}
void ping(void)
{
cout<<"ping command executed";
}
int main()
{
ToDoCommands obj;
obj.getCommand("ping");
}
The function pointer should refer to function ping dynamically. A string same as function name is passed to getCommand function in main.
C++ just doesn't work that way. If you really need something like that, you'll have to make a table of functions that are indexed by name:
#include <assert.h>
#include <iostream>
#include <map>
#include <string>
using std::cout;
using std::string;
using std::map;
void ping(void)
{
cout << "ping command executed\n";
}
class ToDoCommands
{
public:
typedef void (*FunctionPtr)();
typedef string Name;
void registerFunction(Name name,FunctionPtr);
void callFunction(Name);
private:
map<Name,FunctionPtr> func_map;
};
void ToDoCommands::registerFunction(Name name,FunctionPtr func_ptr)
{
func_map[name] = func_ptr;
}
void ToDoCommands::callFunction(Name name)
{
assert(func_map.find(name)!=func_map.end());
func_map[name]();
}
int main(int argc,char **argv)
{
ToDoCommands to_do_commands;
to_do_commands.registerFunction("ping",ping);
to_do_commands.callFunction("ping");
return 0;
}
void ping(void)
{
// LL DD…DD XX
cout<<"ping command executed"<<endl;
}
class ToDoCommands
{
public:
void getCommand( void (*CommandToCall)(void)); //getCommand(ping)
};
void ToDoCommands::getCommand( void (*CommandToCall)(void) )
{
void (*CommandToCall1)(void);
CommandToCall1 = CommandToCall;
CommandToCall1();
}
int main()
{
ToDoCommands obj;
obj.getCommand( ping );
return 0;
}
i tried this and its working :)