1

シリアル ポートから読み取る専用スレッドで実行される関数を作成しようとしています。しかし、接続をスレッドに渡すのに問題があります。コードを次の例に減らしました。

#include <thread>
#include <boost/asio.hpp>

template <typename Port>
void serial_read( Port& port) {}

int main()
{
  boost::asio::io_service serial_io;
  boost::asio::serial_port port( serial_io );
  port.open( "/dev/ttyUSB0" );

  std::thread s( serial_read<boost::asio::serial_port>, port );
  return 0;
}

ただし、次のエラー メッセージが表示されます。

/usr/include/c++/4.7/tuple:128:25: error: use of deleted function ‘boost::asio::basic_serial_port<>::basic_serial_port(const boost::asio::basic_serial_port<>&)’
In file included from /usr/include/boost/asio.hpp:25:0,
                 from main.cpp:2:
/usr/include/boost/asio/basic_serial_port.hpp:47:7: note: ‘boost::asio::basic_serial_port<>::basic_serial_port(const boost::asio::basic_serial_port<>&)’ is implicitly declared as deleted because ‘boost::asio::basic_serial_port<>’ declares a move constructor or move assignment operator

エラーメッセージは非常に明確です。移動コンストラクターの宣言により削除されたために存在しないオブジェクトを使用しようとしています。しかし、ここで何が起こっているのか、正しく行う方法はまだわかりません。誰かが私を啓発できますか?

4

2 に答える 2

3

エラーを正しく読んでいません。のコピー コンストラクタboost::asio::basic_serial_portdeletedであることを示しています。これは、コピー コンストラクターを使用できないことを意味します。オブジェクトの削除とは関係ありません。コピー コンストラクターがdeleted である理由は、ムーブ コンストラクターが定義されているためです。

本当に への参照を渡す必要がある場合は、オブジェクトを でserial_readラップする必要があります。portreference_wrapper

std::thread s( serial_read<boost::asio::serial_port>, std::ref(port) );

ただし、保持して他の目的port(同じportオブジェクトを他のスレッドに渡すなど) に使用しない場合はstd::moveportオブジェクトをスレッドに入れる必要があります。

std::thread s( serial_read<boost::asio::serial_port>, std::move(port) );

これには、 の定義を値serial_readで受け取るように変更する必要もあります。Port

template <typename Port>
void serial_read( Port port) {}
于 2013-03-27T14:56:48.720 に答える
2

簡単な修正(テストされていないと思います)は、参照ラッパーを使用することです(オブジェクトをスレッド内mainとスレッド内の両方で維持する必要がある場合):

std::thread s(&serial_read<boost::asio::serial_port>,std::ref(port));

問題は、後で (引数なしで) 使用されるstd::thread(std::bind引数のコピーでファンクタを作成するように) ことです。基本的に、上記の呼び出しは次のようになります。

std::thread( std::bind(&serial_read<boost::asio::serial_port>,std::ref(port)) );

バインドされたオブジェクトには、各引数のコピーが格納されます。これには、引数がコピー構築可能である必要があります。参照ラッパーを使用すると、コピーが可能になります (ラッパーはコピーされますが、元のオブジェクトはコピーされません)。

portで有効なオブジェクトを維持する必要がない場合の別の方法は、そこから移動することです。これにより、バインドされたオブジェクトにコピーmainする代わりに、実装がでオブジェクトから移動できるようになります。main

于 2013-03-27T14:57:41.253 に答える