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()
);
}
}