I am trying to run the following program using boost::thread.
#include <boost/thread.hpp>
#include <iostream>
using namespace std;
class test{
public:
void hello(int i)
{
cout << i << " ";
};
};
int main(int argc, char* argv[])
{
class test t;
boost::thread thrd(t.hello, 10);
thrd.join();
return 0;
}
It is throwing an error while compiling as given below:
thread.c:17:33: error: no matching function for call to
'boost::thread::thread(, int)'
/usr/include/boost/thread/detail/thread.hpp:236:9: note: candidates
are: boost::thread::thread(F, A1) [with F = void (test::*)(int), A1 =
int] /usr/include/boost/thread/detail/thread.hpp:202:9: note:
boost::thread::thread(boost::detail::thread_move_t)
I am using boost 1.42. I have also tried old style boost::thread creation.
When hello() is not a class function, everything goes fine. Please let me know how can I fix it?
You didn't read the documentation.
You either need to make the hello method function static, or create thread by passing object of type test to it's constructor :
int main(int argc, char* argv[])
{
test t;
boost::thread thrd(&test::hello, &t, 10);
thrd2.join();
}
The problem is you are try to bind to a member function try the following (i don't have your boost version so have no idea if this works for sure)
boost::thread thrd(&test::hello, &t, 10);
Failing that you can use a binder
boost::thread thrd(
boost::bind(&test::hello, &t, 10));
If your compiler is new enough you can use the standard library equivalents of all of those by changing the boost namespace for std:: (the placeholder are in std::placeholders not the global namespace).
std::thread(... //c++11
Try with this code:
int main(int argc, char* argv[])
{
test t;
boost::thread thrd(&test::hello,&t,10);
thrd.join();
return 0;
}
Related
I am trying to write an CLI using boost::program_options to an existing codebase that utilizes a lot of boost::optional arguments so I would like to parse boost::optional's from the command line. If it is not specified, the result is boost::none, and if it is specified I get an initialized value.
When I attempt to do this using a custom Boost validator, I get a bad_any_cast. Below is a MCVE of the problem.
I have a class
class MyClass {
public:
int x;
MyClass(const int a) : x(a) {};
};
and a custom Boost validator for this class. This style of validator was taken straight from the boost docs.
void validate(boost::any& v, const std::vector<std::string>& values,
MyClass* target_type, int) {
v = boost::any(boost::optional<MyClass>(boost::in_place(1)));
}
Lastly, my main function, which creates a simple parser.
#include <boost/program_options.hpp>
#include <boost/optional.hpp>
#include <boost/optional/optional_io.hpp>
#include <boost/utility/in_place_factory.hpp>
int main(int argc, char** argv) {
po::options_description desc("");
desc.add_options()
("MyClass", po::value<boost::optional<MyClass>>()->default_value(boost::none, ""), "MyClass");
po::variables_map args;
po::store(po::parse_command_line(argc, argv, desc), args);
}
When I do not pass the --MyClass options on the command line, the code runs successfully. However, if I pass the --MyClass option, I get a bad_any_cast
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_any_cast> >'
what(): boost::bad_any_cast: failed conversion using boost::any_cast
I stepped through with GDB and this is being thrown in the MyClass any_cast, yet if I write similar code outside of boost::program_options, it works succesfuly.
For example, the following code, that casts the same boost::optional to boost::any and then casts it back, runs without error.
#include <iostream>
#include <boost/program_options.hpp>
#include <boost/optional.hpp>
#include <boost/optional/optional_io.hpp>
#include <boost/utility/in_place_factory.hpp>
namespace po = boost::program_options;
class MyClass {
public:
int x;
MyClass(const int a) : x(a) {};
};
int f(boost::any& v) {
v = boost::any(boost::optional<MyClass>(boost::in_place(1)));
}
int main(int argc, char** argv) {
boost::any v;
f(v);
boost::any_cast<boost::optional<MyClass>>(v);
}
I know that program_options supports default_value so I could use an if statement to wrap the base value in an optional after parsing but I think it would be much cleaner to achive this using the custom validator approach above.
Does anyone have any ideas or suggestions on how to go about fixing this?
The validation function does not take an optional. This is implied by the fact that the type argument (target_type) is MyClass*, not optional<MyClass>*. docs
The function takes four parameters. The first is the storage for the value, and in this case is either empty or contains an instance of the magic_number class. The second is the list of strings found in the next occurrence of the option. The remaining two parameters are needed to workaround the lack of partial template specialization and partial function template ordering on some compilers.
Here's my take on it:
Live On Coliru
#include <boost/optional.hpp>
#include <boost/optional/optional_io.hpp>
#include <boost/program_options.hpp>
#include <boost/utility/in_place_factory.hpp>
#include <iostream>
#include <string>
namespace po = boost::program_options;
struct MyClass {
int x;
MyClass(int a) : x(a){};
friend std::ostream& operator<<(std::ostream& os, MyClass const& mc) {
return os << "MyClass(" << mc.x << ")";
}
};
void validate(boost::any &v, const std::vector<std::string> &values, MyClass * /*target_type*/, int) {
v = MyClass(std::stoi(values.front()));
}
int main(int argc, char **argv) {
po::options_description desc("");
desc.add_options()("MyClass", po::value<boost::optional<MyClass> >()->default_value(boost::none, ""), "MyClass");
po::variables_map args;
store(parse_command_line(argc, argv, desc), args);
notify(args);
std::cout << "Arg: " << args["MyClass"].as<boost::optional<MyClass> >() << "\n";
}
For:
./a.out --MyClass 42
./a.out --MyClass no_chill
./a.out
Prints
+ ./a.out --MyClass 42
Arg: MyClass(42)
+ ./a.out --MyClass no_chill
terminate called after throwing an instance of 'std::invalid_argument'
what(): stoi
+ ./a.out
Arg: --
Bonus
Taking a hints from the docs I think you could make it more elegant:
int main(int argc, char **argv) {
po::options_description desc("");
boost::optional<MyClass> my_option;
desc.add_options()("MyClass", po::value(&my_option), "MyClass");
po::variables_map args;
store(parse_command_line(argc, argv, desc), args);
notify(args);
std::cout << "Arg: " << my_option << "\n";
}
Removing all the error-prone repeating of types and names.
Note: this does not work for boost versions lower than 1.65, and the user will see a static assert error coming from "lexical_cast.hpp" when compiling (see release notes for 1.65).
Live On Coliru
Still the same output.
I built an interface taking pointers to functions. Sometimes this calculation depends on state, which I want to encapsulate in a class and pass its method:
#include <iostream>
class Printer {
public:
static void print(int i) { // Want to get rid of the static
std::cout << i << "\n";
}
};
template<typename int_func>
void with_1(int_func func) {
func(1);
}
int main(int argc, char const *argv[]) {
Printer printer;
with_1(printer.print);
return 0;
}
I need non-static methods (and would even prefer overloading operator()). However removing the static results in error: a pointer to a bound function may only be used to call the function.
I could use a dummy like this:
Printer printer;
void dummy(int i) {
printer.print(i);
}
int main(int argc, char const *argv[]) {
with_1(dummy);
return 0;
}
But that does not look elegant to me. Can I write a template that accepts both, function pointers and non-static methods? Or is there even a better design pattern for my problem?
You can not simply pass non-static method like this, because they work on instance. A simply solution is to use lambda:
#include <iostream>
class Printer {
public:
static void print(int i) { // Want to get rid of the static
std::cout << i << "\n";
}
};
template<typename int_func>
void with_1(int_func func) {
func(1);
}
int main(int argc, char const *argv[]) {
Printer printer;
// Can use capture by reference because we are sure printer still
// exist during execution of with_1
with_1([&printer](int i){ printer.print(i); });
return 0;
}
example
Try this:
int main(int argc, char const *argv[]) {
Printer printer;
with_1( std::bind( &Printer::print, printer, std::placeholders::_1 ) );
return 0;
}
(You'll need to #include <functional>.)
I want my function running in a separate thread. I use Boost library and include like this in my main.cpp:
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
I want the thread start like this:
boost::thread ethread(Engine::function,info);
// info is an object from the class Engine and i need this in the
// function
My Engine class is in the func.h and the function looks like this:
void Engine::function(Engine info)
{
//STUFF
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
}
BTW: Is the sleep function for the thread right?
Every time I want to compile it gives me this error:
error C3867: "Engine::function": function call missing argument list; use '&Engine::function' to create a pointer to member
I tried to use &Engine::function in the thread and this error appears:
error C2064: term does not evaluate to a function taking 2 arguments
I also tried:
boost::thread ethread(Engine::function,info, _1);
Then this error appeared:
error C2784: "result_traits<R,F>::type boost::_bi::list0::operator [](const boost::_bi::bind_t<R,F,L> &) const"
Can someone help me with this? I only want to run the function beside the main thread.
You should use bind function to create functional object with pointer to class member function or make your function static.
http://ru.cppreference.com/w/cpp/utility/functional/bind
More detailed explanation:
boost::thread constructor needs pointer to a function. In case of normal functions syntax is simple: &hello
#include <boost/thread/thread.hpp>
#include <iostream>
void hello()
{
std::cout << "Hello world, I'm a thread!" << std::endl;
}
int main(int argc, char* argv[])
{
boost::thread thrd(&hello);
thrd.join();
return 0;
}
But if you need pointer to a function of class you have to remember that such functions have implicit parameter - this pointer, so you have to pass it also. You can do this by creating callable object with std::bind, or boost bind.
#include <iostream>
#include <boost/thread.hpp>
class Foo{
public:
void print( int a )
{
std::cout << a << std::endl;
}
};
int main(int argc, char *argv[])
{
Foo foo;
boost::thread t( std::bind( &Foo::print, &foo, 5 ) );
t.join();
return 0;
}
This is a minimal code to illustrate what I need. It doesn't work, because (as rightly the error message says when compiling) at_thread_exit is not a member of boost::thread. I know is related to the namespace this_thread, I've been going through the documentation at the boost page, but cannot follow how to use at_thread_exit. I haven't been able to find any simple example of how to use it using google.
#include <boost/thread.hpp>
#include <iostream>
class A{
public:
void callme(){
int a = 1;
}
void runThread() {
boost::thread td(&A::callme,this);
td.at_thread_exit(&A::done,this);
td.join();
}
void done() {
std::cout << "I am done!!!\n";
}
};
int main(int argc, char **argv) {
A *a = new A();
a->runThread();
delete a;
return EXIT_SUCCESS;
}
boost::thread td([this]{
callme();
done();
});
at_thread_exit only works within the same thread; it would require sychronization otherwise, and that would make every thread pay for it when only some threads use it.
So this is confusing to explain, but I will try my best.
I have a function one of my classes that takes a function pointer as an argument, and what I would like to do is define the function as part of the argument. ie:
object->setFunctionPointer({string a = ""; return a;});
Is this possible? if so, what is the proper syntax of this?
In C++11, you can do it. You can use C++ lambda (anonymous functions).
See the sample code at http://ideone.com/8ZTWSU
#include <iostream>
using namespace std;
typedef const char * (*funcptr)();
funcptr s;
void setFuncPtr(funcptr t)
{
s = t;
}
int main() {
// your code goes here
setFuncPtr([]{return "Hello \n"; });
printf("%s\n", s());
return 0;
}
If we are talking about C++ you should use std::function and not function pointers. Unless you are interfacing with C APIs.
class Foo{
SetFunc(std::function<void(int)> func)
{
m_func = func;
}
private:
std::function<void(int)> m_func;
};
If your function is a member of a class, you cannot take an ordinary function pointer to store its address. What you need is a delegate; which are specialised function pointers for methods. Search the internet for C++ delegate and you should find numerous examples.
(Note: maybe there is an exception for static methods; I don't remember.)
Here is a complete example. Since c++11 this is the way to go:
#include<functional>
#include<string>
#include<iostream>
using namespace std;
class Object
{
public:
void setFunctionPointer(function<string(void)> function)
{
m_function = function;
}
string run()
{
return m_function();
}
private:
function<string(void)> m_function;
};
int main(int argc, char**argv)
{
Object *object = new Object;
object->setFunctionPointer([]{string a = "FOO"; return a;}); // here is the function assignment
cout << object->run() << endl;
delete object;
}
When run this prints FOO to stdout.