概括传递给 boost::bind 的参数
Generalize the argument passed to boost::bind
我正在尝试编写一个使用 boost::bind
的通用结构 MyCounter
。我想要做的是编写 MyCounter
这样一种方式,通过更改其模板参数类型,我可以绑定到不同的方法。我的印象是,如果我将 MyThread::send
之类的东西作为模板参数传递,我将能够直接在 bind()
中使用它。显然我错了。您能帮我解决其他问题吗?谢谢
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <vector>
#include <utility>
struct MyThread //simplified
{
void send1()
{
std::cout << "In Send1\n";
}
void send2()
{
std::cout << "In Send2\n";
}
};
struct Job //ignore me
{
Job(const unsigned int interval)
: _tChk(0)
, _tInterval(interval)
{}
void operator()(unsigned long nowSec)
{
if (nowSec > _tChk)
{
_functor();
_tChk += nowSec + _tInterval;
}
}
private:
unsigned long _tChk;
const unsigned int _tInterval;
protected:
boost::function<void()> _functor;
};
struct JobInvoker //ignore me
{
typedef boost::shared_ptr<Job> JobPtr;
JobInvoker(MyThread &myThread)
: _myThread(myThread)
{}
template<typename JOB>
void addJob(const unsigned int interval)
{
JobPtr job = boost::make_shared<JOB>(interval, _myThread);
_jobs.push_back(job);
}
void operator() (JobPtr job)
{
(*job)(_now.tv_sec);
}
void invoke(timeval now)
{
_now = now;
std::for_each(_jobs.begin(), _jobs.end(), *this);
}
timeval _now;
std::vector<JobPtr> _jobs;
MyThread &_myThread;
};
//my struggle
template<typename F>
struct MyCounter : public Job
{
MyCounter(const unsigned int interval, MyThread &myThread)
: Job(interval)
{
_functor = boost::bind(&F, &myThread); //<-- Error
}
};
int main()
{
MyThread t;
JobInvoker jobInvoker(t);
jobInvoker.addJob<MyCounter<MyThread::send1> >(2); //<-- Error
jobInvoker.addJob<MyCounter<MyThread::send2> >(2); //<-- Error
timeval now;//...
jobInvoker.invoke(timeval now)
return 0;
}
更新:
编译:
g++ boost_f.cpp -lboost_system
我们收到以下错误:
boost_f.cpp: In constructor ‘MyCounter<F>::MyCounter(unsigned int, MyThread&)’:
boost_f.cpp:81:34: error: expected primary-expression before ‘,’ token
_functor = boost::bind(&F, &myThread); //<-- Error
^
boost_f.cpp: In function ‘int main()’:
boost_f.cpp:89:46: error: type/value mismatch at argument 1 in template parameter list for ‘template<class F> struct MyCounter’
jobInvoker.addJob<MyCounter<MyThread::send1> >(2); //<-- Error
^
boost_f.cpp:89:46: error: expected a type, got ‘MyThread::send1’
boost_f.cpp:89:51: error: no matching function for call to ‘JobInvoker::addJob(int)’
jobInvoker.addJob<MyCounter<MyThread::send1> >(2); //<-- Error
^
boost_f.cpp:89:51: note: candidate is:
boost_f.cpp:52:10: note: template<class JOB> void JobInvoker::addJob(unsigned int)
void addJob(const unsigned int interval)
^
boost_f.cpp:52:10: note: template argument deduction/substitution failed:
boost_f.cpp:89:51: error: template argument 1 is invalid
jobInvoker.addJob<MyCounter<MyThread::send1> >(2); //<-- Error
^
boost_f.cpp:90:46: error: type/value mismatch at argument 1 in template parameter list for ‘template<class F> struct MyCounter’
jobInvoker.addJob<MyCounter<MyThread::send2> >(2); //<-- Error
^
boost_f.cpp:90:46: error: expected a type, got ‘MyThread::send2’
boost_f.cpp:90:51: error: no matching function for call to ‘JobInvoker::addJob(int)’
jobInvoker.addJob<MyCounter<MyThread::send2> >(2); //<-- Error
^
boost_f.cpp:90:51: note: candidate is:
boost_f.cpp:52:10: note: template<class JOB> void JobInvoker::addJob(unsigned int)
void addJob(const unsigned int interval)
^
boost_f.cpp:52:10: note: template argument deduction/substitution failed:
boost_f.cpp:90:51: error: template argument 1 is invalid
jobInvoker.addJob<MyCounter<MyThread::send2> >(2); //<-- Error
^
boost_f.cpp:92:29: error: expected primary-expression before ‘now’
jobInvoker.invoke(timeval now)
如错误所述,成员函数不是类型,因此不能用于模板类型参数。
相反,您需要使用非类型参数:
template<void(MyThread::*F)()>
struct MyCounter : public Job
{
MyCounter(const unsigned int interval, MyThread &myThread)
: Job(interval)
{
_functor = boost::bind(F, &myThread);
}
};
请注意,我将 F
设为 MyThread
的成员函数指针,而不是 typename
。
我正在尝试编写一个使用 boost::bind
的通用结构 MyCounter
。我想要做的是编写 MyCounter
这样一种方式,通过更改其模板参数类型,我可以绑定到不同的方法。我的印象是,如果我将 MyThread::send
之类的东西作为模板参数传递,我将能够直接在 bind()
中使用它。显然我错了。您能帮我解决其他问题吗?谢谢
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <vector>
#include <utility>
struct MyThread //simplified
{
void send1()
{
std::cout << "In Send1\n";
}
void send2()
{
std::cout << "In Send2\n";
}
};
struct Job //ignore me
{
Job(const unsigned int interval)
: _tChk(0)
, _tInterval(interval)
{}
void operator()(unsigned long nowSec)
{
if (nowSec > _tChk)
{
_functor();
_tChk += nowSec + _tInterval;
}
}
private:
unsigned long _tChk;
const unsigned int _tInterval;
protected:
boost::function<void()> _functor;
};
struct JobInvoker //ignore me
{
typedef boost::shared_ptr<Job> JobPtr;
JobInvoker(MyThread &myThread)
: _myThread(myThread)
{}
template<typename JOB>
void addJob(const unsigned int interval)
{
JobPtr job = boost::make_shared<JOB>(interval, _myThread);
_jobs.push_back(job);
}
void operator() (JobPtr job)
{
(*job)(_now.tv_sec);
}
void invoke(timeval now)
{
_now = now;
std::for_each(_jobs.begin(), _jobs.end(), *this);
}
timeval _now;
std::vector<JobPtr> _jobs;
MyThread &_myThread;
};
//my struggle
template<typename F>
struct MyCounter : public Job
{
MyCounter(const unsigned int interval, MyThread &myThread)
: Job(interval)
{
_functor = boost::bind(&F, &myThread); //<-- Error
}
};
int main()
{
MyThread t;
JobInvoker jobInvoker(t);
jobInvoker.addJob<MyCounter<MyThread::send1> >(2); //<-- Error
jobInvoker.addJob<MyCounter<MyThread::send2> >(2); //<-- Error
timeval now;//...
jobInvoker.invoke(timeval now)
return 0;
}
更新:
编译:
g++ boost_f.cpp -lboost_system
我们收到以下错误:
boost_f.cpp: In constructor ‘MyCounter<F>::MyCounter(unsigned int, MyThread&)’:
boost_f.cpp:81:34: error: expected primary-expression before ‘,’ token
_functor = boost::bind(&F, &myThread); //<-- Error
^
boost_f.cpp: In function ‘int main()’:
boost_f.cpp:89:46: error: type/value mismatch at argument 1 in template parameter list for ‘template<class F> struct MyCounter’
jobInvoker.addJob<MyCounter<MyThread::send1> >(2); //<-- Error
^
boost_f.cpp:89:46: error: expected a type, got ‘MyThread::send1’
boost_f.cpp:89:51: error: no matching function for call to ‘JobInvoker::addJob(int)’
jobInvoker.addJob<MyCounter<MyThread::send1> >(2); //<-- Error
^
boost_f.cpp:89:51: note: candidate is:
boost_f.cpp:52:10: note: template<class JOB> void JobInvoker::addJob(unsigned int)
void addJob(const unsigned int interval)
^
boost_f.cpp:52:10: note: template argument deduction/substitution failed:
boost_f.cpp:89:51: error: template argument 1 is invalid
jobInvoker.addJob<MyCounter<MyThread::send1> >(2); //<-- Error
^
boost_f.cpp:90:46: error: type/value mismatch at argument 1 in template parameter list for ‘template<class F> struct MyCounter’
jobInvoker.addJob<MyCounter<MyThread::send2> >(2); //<-- Error
^
boost_f.cpp:90:46: error: expected a type, got ‘MyThread::send2’
boost_f.cpp:90:51: error: no matching function for call to ‘JobInvoker::addJob(int)’
jobInvoker.addJob<MyCounter<MyThread::send2> >(2); //<-- Error
^
boost_f.cpp:90:51: note: candidate is:
boost_f.cpp:52:10: note: template<class JOB> void JobInvoker::addJob(unsigned int)
void addJob(const unsigned int interval)
^
boost_f.cpp:52:10: note: template argument deduction/substitution failed:
boost_f.cpp:90:51: error: template argument 1 is invalid
jobInvoker.addJob<MyCounter<MyThread::send2> >(2); //<-- Error
^
boost_f.cpp:92:29: error: expected primary-expression before ‘now’
jobInvoker.invoke(timeval now)
如错误所述,成员函数不是类型,因此不能用于模板类型参数。
相反,您需要使用非类型参数:
template<void(MyThread::*F)()>
struct MyCounter : public Job
{
MyCounter(const unsigned int interval, MyThread &myThread)
: Job(interval)
{
_functor = boost::bind(F, &myThread);
}
};
请注意,我将 F
设为 MyThread
的成员函数指针,而不是 typename
。