I was trying this piece of code
demo.hpp
#ifndef DEMO_HPP
#define DEMO_HPP
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <vector>
using namespace std;
typedef boost::function<void(vector<int>)>func;
typedef void (_stdcall *Callback);
class funcPointer
{
public:
void add_call(int, func);
void call_back(int, Callback);
void push_elements();
vector<int> vec;
};
#endif
demo.cpp
#include <iostream>
#include "demo.hpp"
void funcPointer::add_call(int number, func f)
{
cout<<"number: "<<number << endl;
f(vec);
}
void funcPointer::push_elements()
{
vec.push_back(11);
vec.push_back(12);
vec.push_back(13);
}
void funcPointer::call_back(int x, Callback call)
{
cout << "x: " << x <<endl;
}
main.cpp
#include <iostream>
#include "demo.hpp"
void display(vector<int> v)
{
vector<int> ::iterator it;
for(it = v.begin(); it != v.end(); it++)
{
cout<< *it <<endl;
}
}
void Inside_callback()
{
cout << "Hello World" << endl;
}
int main()
{
funcPointer *fun = new funcPointer;
fun->push_elements();
fun->add_call(24, boost::bind(display, _1));
fun->call_back(10, &Inside_callback);
return 0;
}
while compiling I got the following error:
e:\vs_c++\boost_func_ptr\boost_func_ptr\demo.hpp(12): error C2165: 'left-side modifier' : cannot modify pointers to data
I am not able to understand what this error is, and how to get rid of it.
Can somebody help me to get rid of this error??
You have to define type of Callback in following way:
typedef void (_stdcall *Callback)();
You should also modify declaration of Inside_callback in following way for code to compile:
void _stdcall Inside_callback()
Related
I am trying to pass a std::function as a parameter. I am having a couple of problems with the syntax.
The code is simple. I want to save a function handler into a std::map. I don't want to make the registerHandler method a template. Here is the code example.
#include <map>
#include <functional>
#include <iostream>
using namespace std;
class message
{
public:
void print(string command)
{
cout << "message id: " << id_ << " content: " << command << std::endl;
}
int id_ = 0;
};
std::map<int, function<void(string)>> functionMap;
void registerHandler(int id, message& messageClass, std::function<void(string)>& func)
{
auto messageHandler = bind(&func, &messageClass, placeholders::_1);
// ERROR #2
// functionMap.insert({id, messageHandler});
}
int main()
{
message msg1;
msg1.id_ = 5000;
// ERROR #1
// registerHandler(msg1.id_, msg1, message::print);
std::map<int, function<void(string)>>::iterator iter;
iter = functionMap.begin();
while (iter != functionMap.end())
{
int key = iter->first;
auto messageHandler = iter->second;
messageHandler("Junk Payload");
iter++;
}
}
ERROR#1
message.cc:37:44: error: invalid use of non-static member function ‘void message::print(std::string)’
registerHandler(msg1.id_, msg1, message::print);
ERROR#2
message.cc: In function ‘void registerHandler(int, message&, std::function<void(std::basic_string<char>)>&)’:
message.cc:24:42: error: no matching function for call to ‘std::map<int, std::function<void(std::basic_string<char>)> >::insert(<brace-enclosed initializer list>)’
functionMap.insert({id, messageHandler});
^
You can write your program like this to work:
#include <map>
#include <functional>
#include <iostream>
using namespace std;
class message
{
public:
void print(string command)
{
cout << "message id: " << id_ << " content: " << command << std::endl;
}
int id_ = 0;
};
std::map<int, function<void(string)>> functionMap;
void registerHandler(int id, message& messageClass, const std::function<void(string)>& func)
{
functionMap.insert({id, func});
}
int main()
{
message msg1;
msg1.id_ = 5000;
registerHandler(msg1.id_, msg1, bind(&message::print, &msg1, placeholders::_1));
std::map<int, function<void(string)>>::iterator iter;
iter = functionMap.begin();
while (iter != functionMap.end())
{
int key = iter->first;
auto messageHandler = iter->second;
messageHandler("Junk Payload");
iter++;
}
}
#include <iostream>
#include <vector>
#include <string>
#include <any>
#include <map>
#include <functional>
#include <exception>
using namespace std;
using MapAny = std::map<string, any>;
int square(int x) {
return x*x;
}
vector<int> parse(map<string, vector<MapAny>> mapping)
{
vector<MapAny> func_square = mapping["square"];
vector<int> res;
for (const auto &mapany : func_square) {
try {
int x = any_cast<int>(mapany.at("x"));
res.push_back(square(x));
}
catch (exception e) {
vector<int> xs = any_cast<vector<int>>(mapany.at("x"));
for (int x : xs) res.push_back(square(x));
}
}
return res;
}
int main()
{
map<string, vector<MapAny>> function_map_value, function_map_array;
function_map_value = {
{"square", { {{"x", 5}}, {{"x", 10}} }}
};
vector<MapAny> vec;
vec.push_back({{"x", vector<int>({5, 10}) }});
function_map_array = {
{"square", vec}
};
vector<int> res1 = parse(function_map_value);
vector<int> res2 = parse(function_map_array);
for (int i=0; i<res1.size(); i++) cout << res1[i] << " "; cout << "\n";
for (int i=0; i<res2.size(); i++) cout << res2[i] << " "; cout << "\n";
return 0;
}
I'm trying to make a function parser that can accept any type, such as both scalar and vector values, like in Python dict().
However, I'm not sure how to check if a std::any object has type std::vector. In the code above, if any_cast fails, it will throw exception and I know it's a std::vector. It's ugly and rely on throwing exception as an expected behavior.
How can I change the above code into something like:
if (is_vector(mapany.at("x")) {
// deal with vector
}
else {
// deal with scalar
}
I would like to use an unordered_map as a job or session context object. So, I would like to allocate in some function bundle it with a static function in a function object and send this function object to an io_service. And obviously, I do not worry about deallocating it.
Any ideas on how to do that?
Thank you!
#include <iostream>
#include <unordered_map>
#include "boost/asio.hpp"
#include "boost/thread.hpp"
using namespace std;
namespace asio = boost::asio;
typedef std::unique_ptr<asio::io_service::work> work_ptr;
typedef boost::function<void(void) > boost_void_void_fun;
class job_processor {
public:
job_processor(int threads) : thread_count(threads) {
service = new asio::io_service();
work = new work_ptr(new asio::io_service::work(*(service)));
for (int i = 0; i < this->thread_count; ++i)
workers.create_thread(boost::bind(&asio::io_service::run, service));
}
void post_task(boost_void_void_fun job) {
this->service->post(job);
}
void drain() {
this->work->reset();
}
void wait() {
this->workers.join_all();
}
private:
int thread_count;
work_ptr * work;
asio::io_service* service;
boost::thread_group workers;
};
typedef std::unordered_map<string, unsigned long> map_t;
class with_static_function {
public:
static void print_map(map_t map) {
for(map_t::iterator it = map.begin(); it != map.end(); ++it)
std::cout << it->first << ":" << it->second << std::endl;
}
static void print__heap_map(map_t* map) {
if(!map) return;
for(map_t::iterator it = map->begin(); it != map->end(); ++it)
std::cout << it->first << ":" << it->second << std::endl;
}
};
int main(int argc, char** argv) {
map_t words;
words["one"] = 1;
// pass the reference;
with_static_function::print_map(words);
job_processor *pr = new job_processor(4);
{
map_t* heap_map = new map_t;
(*heap_map)["two"] = 2;
// I need this variable to the job_processor;
// and I do not want to worry about deallocation.
// should happen automatically somehow.
// I am ok with changing the variable to be a shared_ptr or
// anything else that works.
boost_void_void_fun fun = boost::bind(
&with_static_function::print__heap_map,
heap_map);
fun(); // if binding was done right this should have worked.
pr->post_task(fun);
}
pr->drain();
pr->wait();
delete pr;
return 0;
}
A number of observations:
Stop Emulating Java. Do not use new unless you're implementing an ownership primitive (smart handle/pointer type). Specifically, just create a pr:
job_processor pr(4);
Same goes for all the members of job_processor (you were leaking everything, and if job_processor were copied, you'd get double-free Undefined Behaviour
The code
// pass the reference;
with_static_function::print_map(words);
passes by value... meaning the whole map is copied
to avoid that copy, fix the print_map signature:
static void print_map(map_t const& map) {
for(map_t::const_iterator it = map.begin(); it != map.end(); ++it)
std::cout << it->first << ":" << it->second << std::endl;
}
Of course, consider just writing
static void print_map(map_t const& map) {
for(auto& e : map)
std::cout << e.first << ":" << e.second << "\n";
}
The "heap" overload of that could be, as my wording implies, an overload. Be sure to remove the useless duplication of code (!):
static void print_map(map_t const* map) {
if (map) print_map(*map);
}
You don't even need that overload because you can simply use a lambda to bind (instead of boost::bind):
auto heap_map = boost::make_shared<map_t>();
heap_map->insert({{"two", 2}, {"three", 3}});
boost_void_void_fun fun = [heap_map] { with_static_function::print_map(*heap_map); };
Complete working program:
Live On Coliru
#include <iostream>
#include <unordered_map>
#include <boost/asio.hpp>
#include <boost/make_shared.hpp>
#include <boost/thread.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
namespace asio = boost::asio;
typedef boost::function<void(void)> boost_void_void_fun;
class job_processor {
public:
job_processor(int threads) : service(), work(boost::asio::io_service::work(service))
{
for (int i = 0; i < threads; ++i)
workers.create_thread(boost::bind(&asio::io_service::run, &service));
}
void post_task(boost_void_void_fun job) {
service.post(job);
}
void drain() {
work.reset();
}
void wait() {
workers.join_all();
}
private:
asio::io_service service;
boost::optional<asio::io_service::work> work;
boost::thread_group workers;
};
typedef std::unordered_map<std::string, unsigned long> map_t;
namespace with_static_function {
static void print_map(map_t const& map) {
for(auto& e : map)
std::cout << e.first << ":" << e.second << "\n";
}
}
int main() {
// pass the reference;
with_static_function::print_map({ { "one", 1 } });
job_processor pr(4);
{
auto heap_map = boost::make_shared<map_t>();
heap_map->insert({{"two", 2}, {"three", 3}});
boost_void_void_fun fun = [heap_map] { with_static_function::print_map(*heap_map); };
pr.post_task(fun);
}
pr.drain();
pr.wait();
}
Prints
one:1
three:3
two:2
The code is :
#include <map>
#include <utility>
typedef struct
{
int d_number;
int o_number;
} d_o_pair;
std::set<d_o_pair> d_o_set;
std::map<int, d_o_set> my_map;
}
i want to insert into the map. but i am not able to
. i was using like this : this->my_map[5].insert(make_pair(0, 2)). the compiler throws me error telling no function matches call to insert
Following sample code tell us inserting into map. For inserting to set, you need to overload the '<' operator to define the ordering condition in the structure with a constructor and insert in a similar fashion using insert function.
#include<iostream>
#include<map>
using namespace std;
typedef struct
{
int d_number;
int o_number;
}d_o_number;
int main()
{
d_o_number s1;
s1.d_number = 100;
s1.o_number = 1000;
std::map<int, d_o_number> d_o_map;
d_o_map.insert(std::pair<int, d_o_number>(0, s1));
// showing contents:
std::map<int,d_o_number>::iterator it = d_o_map.begin();
std::cout << "d_o_map contains:\n";
for (it=d_o_map.begin(); it!=d_o_map.end(); ++it)
std::cout << it->first << " => " << it->second.d_number<<","<<it->second.o_number << '\n';
return 0;
}
Try the following
#include <map>
#include <set>
#include <utility>
typedef std::pair<int, int> d_o_pair;
typedef std::set<d_o_pair> d_o_set;
int main()
{
std::map<int, d_o_set> my_map;
my_map[5].insert( std::make_pair( 0, 2 ) );
}
Or the following
#include <map>
#include <set>
#include <utility>
typedef struct d_o_pair
{
int d_number;
int o_number;
bool operator <( const d_o_pair &rhs ) const
{
return d_number < rhs.d_number || ( !( rhs.d_number < d_number ) && ( o_number < rhs.o_number ) );
}
} d_o_pair;
typedef std::set<d_o_pair> d_o_set;
int main()
{
std::map<int, d_o_set> my_map;
my_map[5].insert( { 0, 2 } );
}
I need to print the values inserted in the vector using Boost.Bind.
Please find the code snippet below:
Please let me know what I am missing here?
class Test
{
int i;
public:
Test() {}
Test(int _i)
{
i = _i;
}
void print()
{
cout << i << ",";
}
};
int main()
{
std::vector<Test> vTest;
Test w1(5);
Test w2(6);
Test w3(7);
vTest.push_back(w1);
vTest.push_back(w2);
vTest.push_back(w3);
std::for_each(vTest.begin(), vTest.end(),boost::bind(boost::mem_fn(&Test::print), _1, ?)); // How do I print Vector elements here?
}
You can do it without boost like this
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
class Test {
int i;
public:
Test() {
}
Test(int _i) {
i = _i;
}
void print() const {
std::cout << i << std::endl;
}
};
int main() {
std::vector<Test> vTest;
Test w1(5);
Test w2(6);
Test w3(7);
vTest.push_back(w1);
vTest.push_back(w2);
vTest.push_back(w3);
// use lambda
std::for_each(vTest.begin(), vTest.end(), [&](const Test& t){ t.print(); });
// use std::bind
std::for_each(vTest.begin(), vTest.end(), std::bind(&Test::print, std::placeholders::_1));
return 0;
}
Maybe you do not want to have the parameter i for your function print() ? If so, you should simply do like this:
std::for_each(vTest.begin(), vTest.end(),boost::bind(&Test::print, _1));
This will output something like this: 5,6,7,. See live.
If you still want to have some argument passed into your function, then you should pass it to bind():
std::for_each(vTest.begin(), vTest.end(),boost::bind(&Test::print, _1, 0));
0 will be your argument for Test::print(). And, in case of your code, you will have next output: 0,0,0,. See live.
If you fix function to next one:
void print(int i)
{
cout << this->i << " " << i << ",";
}
output will be next: 5 0,6 0,7 0,. See live
You don't need bind there.
Just replace the for_each from your code with the below statement.
std::for_each(vTest.begin(), vTest.end(), std::mem_fn(&Test::print)) ;