我正在尝试使用实现operator()
的回调类创建一个线程。该类包含一个纯虚方法。回调使用虚函数进行处理。这是一个封装了这个想法并抛出一些编译器错误的示例:
#include <boost/chrono.hpp>
#include <boost/thread.hpp>
#include <iostream>
class Test {
protected:
int x;
public:
Test(void): x(10) {};
virtual void operator()(void);
boost::thread run(void);
virtual void a(void) = 0;
};
void Test::operator()(void) {
this->a();
x += 10;
std::cout << "Current Value:" << x << std::endl;
}
boost::thread Test::run(void) {
return boost::thread(*this);
}
class Test1 : public Test {
public:
virtual void a(void);
};
void Test1::a(void) {
x--;
}
main() {
Test1 test = Test1();
test.run().join();
}
我在Arch Linux上使用 gcc(GCC)4.9.1 20140903(预发行版)。运行g++ test.cpp -lboost_thread -lboost_system
时出现以下编译器错误:
test.cpp: In member function ‘boost::thread Test::run()’:
test.cpp:22:31: error: no matching function for call to ‘boost::thread::thread(Test&)’
return boost::thread(*this);
^
test.cpp:22:31: note: candidates are:
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:441:9: note: template<class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> boost::thread::thread(F, A1, A2, A3, A4, A5, A6, A7, A8, A9)
thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9):
^
/usr/include/boost/thread/detail/thread.hpp:441:9: note: template argument deduction/substitution failed:
test.cpp:22:31: note: candidate expects 10 arguments, 1 provided
return boost::thread(*this);
^
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:434:9: note: template<class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> boost::thread::thread(F, A1, A2, A3, A4, A5, A6, A7, A8)
thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8):
^
/usr/include/boost/thread/detail/thread.hpp:434:9: note: template argument deduction/substitution failed:
test.cpp:22:31: note: candidate expects 9 arguments, 1 provided
return boost::thread(*this);
^
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:427:9: note: template<class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7> boost::thread::thread(F, A1, A2, A3, A4, A5, A6, A7)
thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7):
^
/usr/include/boost/thread/detail/thread.hpp:427:9: note: template argument deduction/substitution failed:
test.cpp:22:31: note: candidate expects 8 arguments, 1 provided
return boost::thread(*this);
^
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:420:9: note: template<class F, class A1, class A2, class A3, class A4, class A5, class A6> boost::thread::thread(F, A1, A2, A3, A4, A5, A6)
thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6):
^
/usr/include/boost/thread/detail/thread.hpp:420:9: note: template argument deduction/substitution failed:
test.cpp:22:31: note: candidate expects 7 arguments, 1 provided
return boost::thread(*this);
^
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:413:9: note: template<class F, class A1, class A2, class A3, class A4, class A5> boost::thread::thread(F, A1, A2, A3, A4, A5)
thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5):
^
/usr/include/boost/thread/detail/thread.hpp:413:9: note: template argument deduction/substitution failed:
test.cpp:22:31: note: candidate expects 6 arguments, 1 provided
return boost::thread(*this);
^
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:406:9: note: template<class F, class A1, class A2, class A3, class A4> boost::thread::thread(F, A1, A2, A3, A4)
thread(F f,A1 a1,A2 a2,A3 a3,A4 a4):
^
/usr/include/boost/thread/detail/thread.hpp:406:9: note: template argument deduction/substitution failed:
test.cpp:22:31: note: candidate expects 5 arguments, 1 provided
return boost::thread(*this);
^
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:399:9: note: template<class F, class A1, class A2, class A3> boost::thread::thread(F, A1, A2, A3)
thread(F f,A1 a1,A2 a2,A3 a3):
^
/usr/include/boost/thread/detail/thread.hpp:399:9: note: template argument deduction/substitution failed:
test.cpp:22:31: note: candidate expects 4 arguments, 1 provided
return boost::thread(*this);
^
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:392:9: note: template<class F, class A1, class A2> boost::thread::thread(F, A1, A2)
thread(F f,A1 a1,A2 a2):
^
/usr/include/boost/thread/detail/thread.hpp:392:9: note: template argument deduction/substitution failed:
test.cpp:22:31: note: candidate expects 3 arguments, 1 provided
return boost::thread(*this);
^
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:386:9: note: template<class F, class A1> boost::thread::thread(F, A1, typename boost::disable_if<boost::thread_detail::is_convertible<F&, boost::thread_attributes>, boost::thread::dummy*>::type)
thread(F f,A1 a1,typename disable_if<boost::thread_detail::is_convertible<F&,thread_attributes >, dummy* >::type=0):
^
/usr/include/boost/thread/detail/thread.hpp:386:9: note: template argument deduction/substitution failed:
test.cpp:22:31: note: candidate expects 3 arguments, 1 provided
return boost::thread(*this);
^
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:335:9: note: boost::thread::thread(boost::detail::thread_move_t<boost::thread>)
thread(BOOST_THREAD_RV_REF(thread) x) BOOST_NOEXCEPT
^
/usr/include/boost/thread/detail/thread.hpp:335:9: note: no known conversion for argument 1 from ‘Test’ to ‘boost::detail::thread_move_t<boost::thread>’
/usr/include/boost/thread/detail/thread.hpp:325:9: note: template<class F> boost::thread::thread(const attributes&, boost::detail::thread_move_t<T>)
thread(attributes const& attrs, BOOST_THREAD_RV_REF(F) f):
^
/usr/include/boost/thread/detail/thread.hpp:325:9: note: template argument deduction/substitution failed:
test.cpp:22:31: note: cannot convert ‘*(Test*)this’ (type ‘Test’) to type ‘const attributes& {aka const boost::thread_attributes&}’
return boost::thread(*this);
^
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:312:18: note: template<class F> boost::thread::thread(boost::detail::thread_move_t<T>, typename boost::disable_if<boost::is_same<typename boost::decay<F>::type, boost::thread>, boost::thread::dummy*>::type)
explicit thread(BOOST_THREAD_RV_REF(F) f
^
/usr/include/boost/thread/detail/thread.hpp:312:18: note: template argument deduction/substitution failed:
test.cpp:22:31: note: ‘Test’ is not derived from ‘boost::detail::thread_move_t<T>’
return boost::thread(*this);
^
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:303:9: note: template<class F> boost::thread::thread(const attributes&, F, typename boost::disable_if<boost::thread_detail::is_convertible<F&, boost::detail::thread_move_t<T> >, boost::thread::dummy*>::type)
thread(attributes const& attrs, F f
^
/usr/include/boost/thread/detail/thread.hpp:303:9: note: template argument deduction/substitution failed:
test.cpp:22:31: note: cannot convert ‘*(Test*)this’ (type ‘Test’) to type ‘const attributes& {aka const boost::thread_attributes&}’
return boost::thread(*this);
^
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:292:18: note: template<class F> boost::thread::thread(F, typename boost::disable_if_c<boost::thread_detail::is_convertible<F&, boost::detail::thread_move_t<T> >::value, boost::thread::dummy*>::type)
explicit thread(F f
^
/usr/include/boost/thread/detail/thread.hpp:292:18: note: template argument deduction/substitution failed:
/usr/include/boost/thread/detail/thread.hpp: In substitution of ‘template<class F> boost::thread::thread(F, typename boost::disable_if_c<boost::thread_detail::is_convertible<F&, boost::detail::thread_move_t<T> >::value, boost::thread::dummy*>::type) [with F = Test]’:
test.cpp:22:31: required from here
/usr/include/boost/thread/detail/thread.hpp:292:18: error: invalid abstract parameter type ‘Test’
test.cpp:5:7: note: because the following virtual functions are pure within ‘Test’:
class Test {
^
test.cpp:12:22: note: virtual void Test::a()
virtual void a(void) = 0;
^
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:244:9: note: boost::thread::thread()
thread() BOOST_NOEXCEPT;
^
/usr/include/boost/thread/detail/thread.hpp:244:9: note: candidate expects 0 arguments, 1 provided
In file included from /usr/include/boost/thread/thread_only.hpp:22:0,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:191:18: note: boost::thread::thread(boost::detail::thread_data_ptr)
explicit thread(detail::thread_data_ptr data);
^
/usr/include/boost/thread/detail/thread.hpp:191:18: note: no known conversion for argument 1 from ‘Test’ to ‘boost::detail::thread_data_ptr {aka boost::shared_ptr<boost::detail::thread_data_base>}’
In file included from /usr/include/boost/thread/lock_guard.hpp:11:0,
from /usr/include/boost/thread/pthread/thread_data.hpp:11,
from /usr/include/boost/thread/thread_only.hpp:17,
from /usr/include/boost/thread/thread.hpp:12,
from /usr/include/boost/thread.hpp:13,
from test.cpp:2:
/usr/include/boost/thread/detail/thread.hpp:163:7: note: boost::thread::thread(boost::thread&)
BOOST_THREAD_MOVABLE_ONLY(thread)
^
/usr/include/boost/thread/detail/thread.hpp:163:7: note: no known conversion for argument 1 from ‘Test’ to ‘boost::thread&’
当类具有纯虚方法时,似乎使用*this
作为仿函数存在问题。
顺便说一下,该程序的预期输出为Current Value:19
。
答案 0 :(得分:2)
从概念上讲,问题是你正在尝试创建一个Test
对象 - 这是不可能的,因为它有一个纯虚函数。你的相关编译错误隐藏在某处:
/usr/include/boost/thread/detail/thread.hpp:292:18: note: template argument deduction/substitution failed:
/usr/include/boost/thread/detail/thread.hpp: In substitution of ‘template<class F> boost::thread::thread(F, typename boost::disable_if_c<boost::thread_detail::is_convertible<F&, boost::detail::thread_move_t<T> >::value, boost::thread::dummy*>::type) [with F = Test]’:
test.cpp:22:31: required from here
/usr/include/boost/thread/detail/thread.hpp:292:18: error: invalid abstract parameter type ‘Test’
test.cpp:5:7: note: because the following virtual functions are pure within ‘Test’:
class Test {
^
你需要给boost::thread
一些实际上可构造的东西。最简单的只是一个lambda:
boost::thread Test::run(void) {
return boost::thread([this]{
this->operator();
});
}
[更新]或实际上更简单:
boost::thread Test::run(void) {
return boost::thread(&Test::operator(), this);
}
答案 1 :(得分:1)
boost::thread
构造函数要求参数为Copyable,并按值(如果它不是rvalue)获取。所以你希望编译器创建一个抽象的Test
实例,它并不同意:
error: invalid abstract parameter type ‘Test’