尝试编译一个非常简单的类建模 TCP 服务器时,我遇到了一个奇怪的链接器错误。我已将其缩小到我试图调用的一行代码operator=(std::thread&&)
;我调用移动运算符,因为复制构造函数被标记为=delete
.
这是我第一个使用 std::thread 和 C++11 的项目,所以也许我在做一些愚蠢的事情,有什么想法吗?
我列出了代码、编译器选项和编译器输出。
clang++ -g -Weverything -Wall -std=c++11 -stdlib=libc++ -Wno-c++98-compat -Wno-weak-vtables -I../ -I/usr/local/include Main.cpp -c -o Main.o
clang++ -g -Weverything -Wall -std=c++11 -stdlib=libc++ -Wno-c++98-compat -Wno-weak-vtables -I../ -I/usr/local/include deepthgt/AdminHandler.cpp -c -o deepthgt/AdminHandler.o
clang++ -stdlib=libc++ -L/usr/local/boost_1_50_0/stage/lib -L/usr/local/lib -lboost_program_options -lboost_thread -lboost_system -lglog Main.o deepthgt/AdminHandler.o -o bets42
Undefined symbols for architecture x86_64:
"std::__1::__any::__any(...)", referenced from:
__ZNSt3__114__thread_proxyINS_5tupleIJMN6bets428deepthgt12AdminHandlerEFvvENS_17reference_wrapperIS4_EEEEEEEPvSA_ in AdminHandler.o
"__ZNSt3__18__invokeIJNS_17reference_wrapperIN6bets428deepthgt12AdminHandlerEEEEEENS_5__natENS_5__anyEDpOT_", referenced from:
__ZNSt3__114__thread_proxyINS_5tupleIJMN6bets428deepthgt12AdminHandlerEFvvENS_17reference_wrapperIS4_EEEEEEEPvSA_ in AdminHandler.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [bets42] Error 1
//---
class AdminHandler : private boost::noncopyable
{
public:
explicit AdminHandler(const unsigned short port);
~AdminHandler();
void start();
void stop();
private:
void handle();
private:
std::thread thread_;
std::mutex mutex_;
bool doHandle_;
const unsigned short port_;
};
//----
AdminHandler::AdminHandler(const unsigned short port)
: doHandle_(false),
port_(port) {}
AdminHandler::~AdminHandler()
{
stop();
}
void AdminHandler::start()
{
std::lock_guard<std::mutex> lock(mutex_);
if( ! thread_.joinable())
{
doHandle_ = true;
thread_ = std::move(std::thread(&AdminHandler::handle, std::ref(*this))); //this code here is the problem
}
}
void AdminHandler::stop()
{
std::lock_guard<std::mutex> lock(mutex_);
if(thread_.joinable())
{
doHandle_ = false;
thread_.join();
}
}
void AdminHandler::handle()
{
try
{
using boost::asio::ip::tcp;
boost::asio::io_service service;
tcp::acceptor acceptor(service, tcp::endpoint(tcp::v4(), port_));
do
{
tcp::socket socket(service);
acceptor.accept(socket);
boost::system::error_code error;
boost::asio::write(socket, boost::asio::buffer("hello world!"), error);
}
while(doHandle_);
}
catch(const std::exception& e)
{
boost::throw_exception(
Exception(__FILE__, __LINE__)
<< "Failed to start or continue to listen on admin port " << port_
<< "; exception: " << e.what()
);
}
}