<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C/C++</title><link>http://blogs.wankuma.com/izmktr/category/1784.aspx</link><description>C/C++</description><managingEditor>出水 洸太郎</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>出水 洸太郎</dc:creator><title>[C++]mutexいろいろ</title><link>http://blogs.wankuma.com/izmktr/archive/2011/12/16/229756.aspx</link><pubDate>Fri, 16 Dec 2011 00:38:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2011/12/16/229756.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/229756.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2011/12/16/229756.aspx#Feedback</comments><slash:comments>133</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/229756.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/229756.aspx</trackback:ping><description>&lt;p&gt;これは16日目の &lt;a href="http://partake.in/events/597a0fc3-0e3a-47a3-8fc3-4f32ad846a3d"&gt;Boost Advent Calendar 2011&lt;/a&gt; の参加記事です。  &lt;p&gt;マルチスレッドのプログラムを作る場合、切っても切れないのがmutexです。&lt;br&gt;同じリソースにアクセスする時はmutexのロックを使って、&lt;br&gt;複数のスレッドが同時にアクセスするのを制限しないといけません。  &lt;p&gt;例えば、std::cout で文字列を出力するのはスレッドセーフではないので、&lt;br&gt;複数のスレッドから同時に呼び出すと、出力が混じり合うことがあります。&lt;br&gt;なので、こんな感じでmutexを使って排他にしなければなりません。 &lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5a841705-b28b-489f-afc4-9bb79e5cd1d8" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c"&gt;static boost::mutex dispmutex;
void Display(const std::string &amp;amp;fname, const std::string &amp;amp;str){
  boost::mutex::scoped_lock lk(dispmutex);
  std::cout &amp;lt;&amp;lt; fname &amp;lt;&amp;lt; ":" &amp;lt;&amp;lt; str &amp;lt;&amp;lt; std::endl;
} &lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;scoped_lockを使うことで、そのスコープの間だけロックを掛ける、ということができます。&lt;br&gt;途中でreturnやbreakなどでスコープを抜けた場合もロックを外してくれるので、&lt;br&gt;mutexのlock/unlockを使うよりは、scoped_lockを使うといいでしょう。 
&lt;p&gt;&amp;nbsp; &lt;p&gt;さて、預金管理システムを作ってみました。&lt;br&gt;残高照会、預け入れ、引き出しができます。&lt;br&gt;預け入れに上限チェックしていませんが、&lt;br&gt;私の預金が32bitの上限が超えそうなときまでには考えます。 
&lt;p&gt;なお、どの関数も1秒ほどの処理時間がかかるものとします。 &lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:b8021d5e-08e6-419f-8bf3-f87a4f1eeb93" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c"&gt;class Yokin{
  boost::mutex access;
  int money;
public:
  Human(int money):money(money){}
  void Zandaka(){
    boost::scoped_lock lk(access);
    Display(__FUNCTION__, boost::lexical_cast&amp;lt;std::string&amp;gt;(money));
  } 

  void Azukeire(int h){
    boost::scoped_lock lk(access);
    money += h;
    Display(__FUNCTION__, boost::lexical_cast&amp;lt;std::string&amp;gt;(money));
  } 

  void Hikidashi(int h){
    boost::scoped_lock lk(access);
    if (h &amp;lt;= money){
      money -= h;
    }
    Display(__FUNCTION__, boost::lexical_cast&amp;lt;std::string&amp;gt;(money));
  }
}; 

&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは無駄な部分があるので、高速化してみます。&lt;br&gt;Zandaka()は値を読み込んで表示しているだけですので、&lt;br&gt;Azukeire()やHikidashi()が動いていない間なら並列で走らせても問題なさそうです。 
&lt;p&gt;そこで、boost::mutexより細かくロックレベルを変えられるのがboost::shared_mutexです。&lt;br&gt;それを使って先ほどのクラスを書き換えてみます。 &lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:38c5393b-47fb-41b3-a780-1fc24f5d7bb2" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c"&gt;class Yokin{
  boost::shared_mutex access;
  int money;
public:
  Human(int money):money(money){}
  void Zandaka(){
    boost::shared_lock&amp;lt;boost::shared_mutex&amp;gt; read(access);
    Display(__FUNCTION__, boost::lexical_cast&amp;lt;std::string&amp;gt;(money));
  } 

  void Azukeire(int h){
    boost::unique_lock&amp;lt;boost::shared_mutex&amp;gt; write(access);
    money += h;
    Display(__FUNCTION__, boost::lexical_cast&amp;lt;std::string&amp;gt;(money));
  } 

  void Hikidashi(int h){
    boost::unique_lock&amp;lt;boost::shared_mutex&amp;gt; write(access);
    if (h &amp;lt;= money){
      money -= h;
    }
    Display(__FUNCTION__, boost::lexical_cast&amp;lt;std::string&amp;gt;(money));
  }
}; 

&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;値を読むだけならshared_lockを使い並列に動くようにして、&lt;br&gt;値を書き換える場合はunique_lockを使って排他にします。&lt;br&gt;これで、残高照会中に別スレッドの残高照会が動くようになって高速化しました。 
&lt;p&gt;しかし、もうちょっと高速化の余地があります。&lt;br&gt;Hikidashi()を見てみると、お金が足りない時はデータを書き換えません。&lt;br&gt;つまり、お金があるときのみ、unique_lockをすればよいです。&lt;br&gt;それを踏まえて書き換えてみます。 &lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:62435df3-1dfa-4fe8-93a7-c01ea8daa765" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c"&gt;  void Hikidashi(int h){
    boost::shared_lock&amp;lt;boost::shared_mutex&amp;gt; shared(access);
    if (h &amp;lt;= money){
　    boost::unique_lock&amp;lt;boost::shared_mutex&amp;gt; unique(access);
      money -= h;
    }
    Display(__FUNCTION__, boost::lexical_cast&amp;lt;std::string&amp;gt;(money));
  } &lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;更に高速化！…するどころか、返ってきません。&lt;br&gt;どうやら、デッドロックしているようです。 
&lt;p&gt;お金を減らすとき、unique_lockを通過するには&lt;br&gt;shared_lockを含め、すべてのロックが外れていることが条件です。&lt;br&gt;しかし、自分自身がshared_lockをかけています。 &lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:371727ca-d939-4a2e-9bf8-884b6f92b0ac" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c"&gt;  void Hikidashi(int h){
    boost::shared_lock&amp;lt;boost::shared_mutex&amp;gt; shared(access);
    if (h &amp;lt;= money){
      shared.unlock();
　    boost::unique_lock&amp;lt;boost::shared_mutex&amp;gt; unique(access);
      money -= h;
    }
    Display(__FUNCTION__, boost::lexical_cast&amp;lt;std::string&amp;gt;(money));
  } &lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;スコープの途中でも、unlock関数を使うことで、ロックを外すことができます。&lt;br&gt;もう使わない！となったらすぐに開放したほうがいいでしょう。 
&lt;p&gt;こうして、デッドロックはなくなりましたが…残高がマイナス？？&lt;br&gt;どうやら、if文を抜けた後、別のスレッドで値を書き換えられたようです。 
&lt;p&gt;ロックは一度確保したら使い終わるまで一瞬でも開放してはいけません。&lt;br&gt;今回はshared_lockのアンロック→unique_lockの間に一瞬ロックが外れていて&lt;br&gt;その間に別のスレッドが値を書き換えているわけです。 
&lt;p&gt;こういう、書き換えるかもしれないときに使うロックがupgrade_lockです。 &lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:6e5ad22e-b68c-413d-a2eb-3451bdd98b9a" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c"&gt;  void Hikidashi(int h){
    boost::upgrade_lock&amp;lt;boost::shared_mutex&amp;gt; upgrade(access);
    if (h &amp;lt;= money){
      boost::upgrade_to_unique_lock&amp;lt;boost::shared_mutex&amp;gt; write(upgrade);
      money -= h;
    }
    Display(__FUNCTION__, boost::lexical_cast&amp;lt;std::string&amp;gt;(money));
  } &lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;upgrade_lockはshared_lockとは干渉しないので&lt;br&gt;引き出し額が足りないときはZandaka()とは並列して動きます。&lt;br&gt;引き出し額が足りているときは、upgrade_to_unique_lockを使ってunique_lockに切りかえ、&lt;br&gt;その時にshared_lockが解除されるまで待ちます。 
&lt;p&gt;まとめると以下のようになります。&lt;/p&gt;
&lt;table border="1" cellspacing="0" cellpadding="2"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;shared_lock&lt;/td&gt;
&lt;td&gt;unique_lockがあるときにブロック&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;upgrade_lock&lt;/td&gt;
&lt;td&gt;upgrade_lock, unique_lockがあるときにブロック&lt;br&gt;unique_lockに変更可能&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;unique_lock&lt;/td&gt;
&lt;td&gt;shared_lock, upgade_lock, unique_lockがあるときにブロック&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;アクセスが集中するリソースではこれらのロックを適切に使っていきたいです。&lt;/p&gt;
&lt;p&gt;以上、Boost Advent Calender 2011 16日目、shared_mutexの紹介でした。&lt;br&gt;明日の17日目は &lt;a href="http://dev.activebasic.com/egtra/"&gt;@egtra&lt;/a&gt; さんです。&lt;br&gt;よろしくお願いします。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/229756.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C++]あちこちを転々と shared_ptr</title><link>http://blogs.wankuma.com/izmktr/archive/2010/10/28/194303.aspx</link><pubDate>Thu, 28 Oct 2010 11:20:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2010/10/28/194303.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/194303.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2010/10/28/194303.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/194303.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/194303.aspx</trackback:ping><description>&lt;p&gt;前回の続きです。&lt;br&gt;&lt;a href="http://blogs.wankuma.com/izmktr/archive/2010/10/26/194241.aspx"&gt;[C++]楽々TCPサーバ&lt;/a&gt;&lt;/p&gt; &lt;p&gt;前回紹介したソースなのですが、その中でtcp_connectionについて解説します。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5d33c0ba-478b-4feb-8f67-41926436ee9a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;class tcp_connection
  : public boost::enable_shared_from_this&amp;lt;tcp_connection&amp;gt;{

  void start_receive(){
    socket_.async_receive(
      boost::asio::buffer(recv_buffer_), 
      boost::bind(&amp;amp;tcp_connection::handle_receive, shared_from_this(),
      boost::asio::placeholders::error, _2));
  }
};

&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;前回作成したtcp_connectionをもうちょっと見てみましょう。&lt;/p&gt;
&lt;p&gt;よく見ると、boost::enable_shared_from_this というクラスから派生しています。&lt;br&gt;そして、async_recieveの引数をよく見ると、shared_from_thisという関数が見えます。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:df408ca4-0ee5-41de-b351-d8a8efb97c2c" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;class udp_server{

  void start_receive(){
    socket_.async_receive_from(
      boost::asio::buffer(recv_buffer_), remote_endpoint_,
      boost::bind(&amp;amp;udp_server::handle_receive, this,
        boost::asio::placeholders::error, _2));
  }
};&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;同じ部分をUDPサーバで見てみましょう。&lt;br&gt;shared_from_this()の部分はただのthisですね。&lt;br&gt;UDPとTCPの差…ではありません、実体の差です。&lt;/p&gt;
&lt;p&gt;実体…つまりどこで変数が確保されているか、です。&lt;br&gt;udp_serverクラスはmain関数内で確保されています。&lt;br&gt;では、tcp_connectionクラスはどこでしょうか。&lt;/p&gt;
&lt;p&gt;前回にちょこっと書いたとおり、tcp_connection::create()関数が呼ばれているところを探せばいいのです。&lt;br&gt;tcp_server::start_accept()にありますね。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9abad47c-c7f7-4a0a-b0d4-f49515730101" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;classs tcp_connection{
  typedef boost::shared_ptr&amp;lt;tcp_connection&amp;gt; pointer;
};

class tcp_server{

  void start_accept(){
    tcp_connection::pointer new_connection =
      tcp_connection::create(acceptor_.io_service());

    acceptor_.async_accept(new_connection-&amp;gt;socket(),
      boost::bind(&amp;amp;tcp_server::handle_accept, this, new_connection,
      boost::asio::placeholders::error));
  }
};
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;tcp_connection::pointerってのはtcp_connectionをshared_ptrで包んだものです。&lt;br&gt;shared_ptrなので、この関数を抜けたときに開放され…ると困りますね。&lt;br&gt;handle_acceptに引数として渡されているので、handle_accept関数が終わるまでは生きています。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:95da7765-b851-44f4-89f0-6f0d7b049595" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;  void handle_accept(tcp_connection::pointer new_connection,
    const boost::system::error_code&amp;amp; error){
    if (!error){
      new_connection-&amp;gt;start();
      start_accept();
    }
  }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ここでは、もうnew_connectionを持ち続けてはいません。&lt;br&gt;この関数を抜けたところで、tcp_connectionは開放されそうです。&lt;/p&gt;
&lt;p&gt;いや、おかしいです。&lt;br&gt;逆にいつまで生きていて欲しいか、を考えると、TCPの通信が切断されるまで生きてないと困ります。&lt;/p&gt;
&lt;p&gt;そこで、最初のtcp_connection::start_acceptに戻ります。&lt;br&gt;thisの代わりにshared_from_thisを使っています。&lt;br&gt;つまり、自分自身のshared_ptrを待ち受けイベントに忍び込ますことで、&lt;br&gt;自分自身が開放されるのを防いでいるわけです。&lt;/p&gt;
&lt;p&gt;そして、だれも次の待ち受けイベントを登録しなくなった次点でtcp_connectionは開放されます。 
&lt;p&gt;なお、shared_from_this(this)と書く代わりにboost::shared_ptr(this)ではだめなのか。&lt;br&gt;shared_ptrはすでに作られているshared_ptrを探してくるわけではありません。&lt;br&gt;つまり、ポインタを管理するクラスが2つ出来てしまい、二重管理になってしまいます。 
&lt;p&gt;ここで出てきたshared_from_thisを提供するクラスが、boost::enable_shared_from_thisです。&lt;br&gt;内部的に自分自身のweak_ptrを持っています。&lt;br&gt;で、必要に応じてweak_ptrをshared_ptrに変換して、渡してあげるわけです。&lt;/p&gt;
&lt;p&gt;shared_ptrでなくweak_ptrの理由は、shared_ptrだと自分自身がもっているものを捨てないと&lt;br&gt;自分自身が解放されないという、一種の循環参照になっているためです。&lt;/p&gt;
&lt;p&gt;ということで、shared_ptrをうまく使う事で管理するクラスを作ってないのに&lt;br&gt;必要なくなったときに解放されるというtcp_connectionクラスを作っています。&lt;br&gt;もう、なんというか無茶苦茶ですね。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/194303.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C++]楽々TCPサーバ</title><link>http://blogs.wankuma.com/izmktr/archive/2010/10/26/194241.aspx</link><pubDate>Tue, 26 Oct 2010 09:34:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2010/10/26/194241.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/194241.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2010/10/26/194241.aspx#Feedback</comments><slash:comments>41</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/194241.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/194241.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/izmktr/archive/2010/10/23/194133.aspx"&gt;[C++]楽々UDPサーバ&lt;/a&gt;&lt;/p&gt; &lt;p&gt;ということで、今回はTCPサーバです。&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:a0a500aa-16e6-4cc1-ab89-b3942c249ec6" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;boost/array.hpp&amp;gt;
#include &amp;lt;boost/bind.hpp&amp;gt;
#include &amp;lt;boost/shared_ptr.hpp&amp;gt;
#include &amp;lt;boost/enable_shared_from_this.hpp&amp;gt;
#include &amp;lt;boost/asio.hpp&amp;gt;

using boost::asio::ip::tcp;

class tcp_connection
  : public boost::enable_shared_from_this&amp;lt;tcp_connection&amp;gt;{
  tcp::socket socket_;
  boost::array&amp;lt;char, 4096&amp;gt; recv_buffer_;

private:
  tcp_connection(boost::asio::io_service&amp;amp; io_service)
    : socket_(io_service){}

  void handle_write(boost::shared_ptr&amp;lt;std::vector&amp;lt;char&amp;gt; &amp;gt; /* sendbuf */, size_t /* len */ ){}

  void handle_receive(const boost::system::error_code&amp;amp; error, size_t len)
  {
    if (!error || error == boost::asio::error::message_size){
      /* メッセージ表示 */
      std::string message(recv_buffer_.data(), len);
      std::cout &amp;lt;&amp;lt; message &amp;lt;&amp;lt; std::endl;

      /* エコー */
      boost::shared_ptr&amp;lt;std::vector&amp;lt;char&amp;gt; &amp;gt; sendbuf( 
        new std::vector&amp;lt;char&amp;gt;(recv_buffer_.begin(), recv_buffer_.begin() + len) );

      boost::asio::async_write(socket_, boost::asio::buffer(*sendbuf),
        boost::bind(&amp;amp;tcp_connection::handle_write, shared_from_this(), sendbuf, len));

      start_receive();
    }
  }

  void start_receive(){
    socket_.async_receive(
      boost::asio::buffer(recv_buffer_), 
      boost::bind(&amp;amp;tcp_connection::handle_receive, shared_from_this(),
      boost::asio::placeholders::error, _2));
  }
public:
  typedef boost::shared_ptr&amp;lt;tcp_connection&amp;gt; pointer;

  static pointer create(boost::asio::io_service&amp;amp; io_service){
    return pointer(new tcp_connection(io_service));
  }

  tcp::socket&amp;amp; socket(){
    return socket_;
  }

  void start(){
    std::cout &amp;lt;&amp;lt; socket_.remote_endpoint().address() &amp;lt;&amp;lt; ":" &amp;lt;&amp;lt; socket_.remote_endpoint().port() &amp;lt;&amp;lt; std::endl ;

    start_receive();
  }
};

class tcp_server{
  tcp::acceptor acceptor_;
  void start_accept(){
    tcp_connection::pointer new_connection =
      tcp_connection::create(acceptor_.io_service());

    acceptor_.async_accept(new_connection-&amp;gt;socket(),
      boost::bind(&amp;amp;tcp_server::handle_accept, this, new_connection,
      boost::asio::placeholders::error));
  }

  void handle_accept(tcp_connection::pointer new_connection,
    const boost::system::error_code&amp;amp; error){
    if (!error){
      new_connection-&amp;gt;start();
      start_accept();
    }
  }
public:
  tcp_server(boost::asio::io_service&amp;amp; io_service, int port)
    : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)){
      start_accept();
  }
};

int main(){
  try{
    boost::asio::io_service io_service;
    tcp_server server1(io_service, 10000);
//  udp_server server2(io_service, 10000);
    io_service.run();
  }
  catch (std::exception&amp;amp; e){
    std::cerr &amp;lt;&amp;lt; e.what() &amp;lt;&amp;lt; std::endl;
  }

  return 0;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;TCPのサーバを作った人ならわかるでしょうが、TCPには2つの段階があります。&lt;/p&gt;
&lt;p&gt;まず、相手からの接続を受け付けるためのリスナーを作成します。&lt;br&gt;その後、誰かが接続してくればそこで接続を確立し、再度リスナーは待ち受けに戻ります。&lt;/p&gt;
&lt;p&gt;まずはその部分から見てみましょう。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7f3e877d-182e-4e59-82f5-98cc03ccc6a6" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;  tcp_server(boost::asio::io_service&amp;amp; io_service, int port)
    : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)){
      start_accept();
  }
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;コンストラクタです。&lt;br&gt;UDPとほぼ同じと言っていいでしょう。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e68e6376-8f4a-4b6d-a0eb-6345a805918a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;  void start_accept(){
    tcp_connection::pointer new_connection =
      tcp_connection::create(acceptor_.io_service());

    acceptor_.async_accept(new_connection-&amp;gt;socket(),
      boost::bind(&amp;amp;tcp_server::handle_accept, this, new_connection,
      boost::asio::placeholders::error));
  }
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ここで、リスナーのイベントを登録します。&lt;br&gt;リスナーの待ち受けにソケットクラスが必要なので、&lt;br&gt;この時点で接続した時のクラスを作っておきます。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:2552bd33-5cfe-4f80-a032-b24419cff484" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;  void handle_accept(tcp_connection::pointer new_connection,
    const boost::system::error_code&amp;amp; error){
    if (!error){
      new_connection-&amp;gt;start();
      start_accept();
    }
  }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;接続時のハンドルクラスです。&lt;br&gt;new_connectionに接続した時の処理を行ない、再度リスナーに待ち受けイベントを登録します。&lt;br&gt;&lt;br&gt;次は接続したときの相手をするtcp_connectionクラスです。&lt;/p&gt;
&lt;p&gt;コンストラクタ、createは省略します。ま、見ればわかりますね。&lt;br&gt;なお、コンストラクタがprivateにあるのはnewで他のクラスから生成できないようにするためです。&lt;br&gt;newの代わりにcreate関数を使ってね、って事ですね。&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:bb15b078-1aba-4fbc-861d-19ea9393f428" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;  void start(){
    std::cout &amp;lt;&amp;lt; socket_.remote_endpoint().address() &amp;lt;&amp;lt; ":" &amp;lt;&amp;lt; socket_.remote_endpoint().port() &amp;lt;&amp;lt; std::endl ;

    start_receive();
  }
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;接続してきたら、誰か接続してきたのかを表示して、パケットが飛んできた時の待ち受けを行ないます。&lt;br&gt;socket_.remote_endpoint()で誰が接続したのかを取り出すことが出来ます。&lt;br&gt;なお、socket_.local_endpoint()は自分自身のIPやポートが入っていますので注意。&lt;/p&gt;
&lt;p&gt;start_receive関数も省略。ただイベント登録しているだけですね。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:65f315a5-20bc-44c8-b91d-ce64b1c06bc0" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;  void handle_receive(const boost::system::error_code&amp;amp; error, size_t len)
  {
    if (!error || error == boost::asio::error::message_size){
      /* メッセージ表示 */
      std::string message(recv_buffer_.data(), len);
      std::cout &amp;lt;&amp;lt; message &amp;lt;&amp;lt; std::endl;

      /* エコー */
      boost::shared_ptr&amp;lt;std::vector&amp;lt;char&amp;gt; &amp;gt; sendbuf( 
        new std::vector&amp;lt;char&amp;gt;(recv_buffer_.begin(), recv_buffer_.begin() + len) );

      boost::asio::async_write(socket_, boost::asio::buffer(*sendbuf),
        boost::bind(&amp;amp;tcp_connection::handle_write, shared_from_this(), sendbuf, len));

      start_receive();
    }
  }
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;UDPサーバと同じく、相手から送られたメッセージを画面に表示して、&lt;br&gt;その後送られたパケットをそのまま投げ返しています。&lt;/p&gt;
&lt;p&gt;なお、async_writeというのを使っています。&lt;br&gt;UDPと同じく、send関数を使ってもいいのですが、非同期送信を使ってみました。&lt;br&gt;送信が終了したらhandle_write関数が呼び出されます。&lt;/p&gt;
&lt;p&gt;send関数を使う場合は送信用バッファをローカルに確保しても良いのですが、&lt;br&gt;非同期送信なのでローカルに確保するとまずいことになります。&lt;br&gt;また、メンバー変数として確保してもやはり先にhandle_recieveが先に2回呼ばれてしまうと、&lt;br&gt;最初のバッファが2回目のデータで上書きされてしまいます。&lt;br&gt;そこで、shared_ptrを使い、毎回送信用バッファを作成しているわけです。&lt;/p&gt;
&lt;p&gt;handle_writeは何もしていません。&lt;br&gt;特に送信後に何かを行うイベントがないのでこうなっています。&lt;br&gt;ではこの関数は要らないの？と思いますが、引数に送信バッファを持っています。&lt;br&gt;つまり、このshared_ptrがこの関数が終わるまで生きているわけです。&lt;br&gt;この関数は送信後に呼ばれるため、送信用バッファを送信後に破棄するためにこの関数が必要になります。&lt;/p&gt;
&lt;p&gt;ということで、TCPサーバも100行程度で作れました。&lt;br&gt;いやぁ、boost便利ですね！&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/194241.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C++]あれがarrayか</title><link>http://blogs.wankuma.com/izmktr/archive/2010/10/24/194169.aspx</link><pubDate>Sun, 24 Oct 2010 08:31:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2010/10/24/194169.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/194169.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2010/10/24/194169.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/194169.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/194169.aspx</trackback:ping><description>&lt;p&gt;boost::arrayの紹介しているページで、こんな記述が。&lt;br&gt;&lt;a href="http://www.kmonos.net/alang/boost/classes/array.html"&gt;letsboost::array&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:64b5b352-5fc6-4da0-acf9-fbf7d4fa0ad6" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;boost::array&amp;lt;int, 4&amp;gt; ar2 = {{0, 100, 200, 300}};
// 普通の配列似の初期化&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;中括弧が２つ？？　なにこれ？？&lt;br&gt;で、調べた結果です。&lt;/p&gt;
&lt;p&gt;boost::arrayって大雑把にカットすると、こういう事なんです。&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:561b425c-1654-4366-8e82-3f2bdff8d094" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;struct array{
  int elems[4];
};
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;で、思い出して欲しいのがこんな書き方。&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:dd4fb67e-9317-413b-b5f4-f067f6d97e91" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;struct Point{
  int x, y;
};

Point pos = {10, 20};&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;C言語時代では良くある初期化ですね。&lt;/p&gt;
&lt;p&gt;これを踏まえた上で、下の書き方を見てみると…。&lt;br&gt;ほら、普通の書き方だ！！&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:23beb547-f263-4643-9922-32c489070e6c" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;int elems[4] = {0, 100, 200, 300};

struct array ary = { {0, 100, 200, 300} };&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;なお、コンストラクタを持つとこういう初期化はできなくなります。&lt;br&gt;出来るのはPOD型ってやつですね。&lt;br&gt;ということで、boost::arrayはPOD型で作ってあります。&lt;/p&gt;
&lt;p&gt;なお、別に中括弧2つ重ねなくても不思議な力によってエラーもでないし問題なく動きます。&lt;br&gt;initializer_listの関係ですかね？&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/194169.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C++]楽々UDPサーバ</title><link>http://blogs.wankuma.com/izmktr/archive/2010/10/23/194133.aspx</link><pubDate>Sat, 23 Oct 2010 09:13:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2010/10/23/194133.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/194133.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2010/10/23/194133.aspx#Feedback</comments><slash:comments>98</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/194133.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/194133.aspx</trackback:ping><description>&lt;p&gt;最近boostを真面目に使い始めたので、その辺を書いてみます。&lt;br&gt;今回はudpサーバの作り方です。&lt;/p&gt; &lt;p&gt;TCPじゃなくてUDP？って感じですが、UDPの方がシンプルなのでまずはこちらを理解しましょう。&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7cbd9f80-35b7-4f44-86fd-8704c6c6d955" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;#include &amp;lt;ctime&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;boost/array.hpp&amp;gt;
#include &amp;lt;boost/bind.hpp&amp;gt;
#include &amp;lt;boost/shared_ptr.hpp&amp;gt;
#include &amp;lt;boost/enable_shared_from_this.hpp&amp;gt;
#include &amp;lt;boost/asio.hpp&amp;gt;

using boost::asio::ip::udp;

class udp_server
{
  udp::socket socket_;
  udp::endpoint remote_endpoint_;
  boost::array&amp;lt;char, 512&amp;gt; recv_buffer_;

public:
  udp_server(boost::asio::io_service&amp;amp; io_service, int port)
    : socket_(io_service, udp::endpoint(udp::v4(), port)){
    start_receive();
  }

private:
  void start_receive(){
    socket_.async_receive_from(
      boost::asio::buffer(recv_buffer_), remote_endpoint_,
      boost::bind(&amp;amp;udp_server::handle_receive, this,
        boost::asio::placeholders::error, _2));
  }

  void handle_receive(const boost::system::error_code&amp;amp; error, size_t len){
    if (!error || error == boost::asio::error::message_size){
      std::string message(recv_buffer_.data(), len);

      std::cout &amp;lt;&amp;lt; remote_endpoint_.address() &amp;lt;&amp;lt; ":" &amp;lt;&amp;lt; remote_endpoint_.port() &amp;lt;&amp;lt; std::endl ;
      std::cout &amp;lt;&amp;lt; message &amp;lt;&amp;lt; std::endl;

      socket_.send_to(boost::asio::buffer(recv_buffer_, len), remote_endpoint_);

      start_receive();
    }
  }
};

int main(){
  try{
    boost::asio::io_service io_service;
    udp_server userver(io_service, 10000);
    io_service.run();
  }
  catch (std::exception&amp;amp; e)  {
    std::cerr &amp;lt;&amp;lt; e.what() &amp;lt;&amp;lt; std::endl;
  }

  return 0;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;udp_serverクラスを見てみましょう。まずは変数部分。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:a7e0d3ef-ae2e-4391-97aa-210019b2c2e4" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;  udp::socket socket_;
  udp::endpoint remote_endpoint_;
  boost::array&amp;lt;char, 512&amp;gt; recv_buffer_;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;変数は3つ、ソケット、エンドポイント、それと受信用バッファですね。&lt;br&gt;エンドポイントってのは、IPやらポートやらを格納するクラスです。&lt;br&gt;今回はパケットの送信元を格納するために使います。&lt;/p&gt;
&lt;p&gt;バッファにboost::arrayを使っていますが、従来のchar [512]の書式だと、&lt;br&gt;どれだけの長さのバッファが確保されているのか、ってのを取得する方法がないんですね。&lt;br&gt;(sizeofを使った取得方法が一応ありますけど…)&lt;br&gt;foreachやイテレータにも対応しているので、使えるときにはこちらを使いましょう。&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5deddea5-03d5-4aac-a8e2-b484dd01350d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;  udp_server(boost::asio::io_service&amp;amp; io_service, int port)
    : socket_(io_service, udp::endpoint(udp::v4(), port)){
    start_receive();
  }
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;コンストラクタでは、ソケットにio_serviceとUDPサーバに必要な物を渡します。&lt;br&gt;そして、start_receiveって関数を呼んでいます。&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7c9e165a-a895-4989-b625-f69d7ff1c305" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;  void start_receive(){
    socket_.async_receive_from(
      boost::asio::buffer(recv_buffer_), remote_endpoint_,
      boost::bind(&amp;amp;udp_server::handle_receive, this,
        boost::asio::placeholders::error, _2));
  }
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;start_recieveってのはパケットを受信した時のイベント登録をする関数です。&lt;br&gt;async_で始まるのは非同期イベントの登録を意味します。&lt;br&gt;つまり、UDPのパケットを受け取ったら、handle_receive関数を呼び出すイベントを登録しています。 
&lt;p&gt;boost::bindのおかげでメンバー関数をコールバックできる当たりが素敵。 
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:2b2a8618-8fdf-4e42-a1a6-0fc4887accf8" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;  void handle_receive(const boost::system::error_code&amp;amp; error, size_t len){
    if (!error || error == boost::asio::error::message_size){
      std::string message(recv_buffer_.data(), len);

      std::cout &amp;lt;&amp;lt; remote_endpoint_.address() &amp;lt;&amp;lt; ":" &amp;lt;&amp;lt; remote_endpoint_.port() &amp;lt;&amp;lt; std::endl ;
      std::cout &amp;lt;&amp;lt; message &amp;lt;&amp;lt; std::endl;

      socket_.send_to(boost::asio::buffer(recv_buffer_, len), remote_endpoint_);

      start_receive();
    }
  }
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;その呼び出されるhandle_receiveの中身。 
&lt;p&gt;handle_receive関数はエラーでも呼び出されるので、エラーでない時だけ通常処理をします。&lt;br&gt;受信したデータをIP、ポートと一緒に画面に表示し、送信元に投げ返します。&lt;br&gt;その後、再度イベントを登録します。&lt;/p&gt;
&lt;p&gt;一度イベントが呼び出された時点でイベントの登録が無効になるので、&lt;br&gt;もう一度登録しなおさないと駄目なんですね。&lt;/p&gt;
&lt;p&gt;ちなみに、message_sizeってのはバッファがあふれた時のエラーです。&lt;br&gt;このエラーは無視します。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:ed6db934-7ddd-458b-a185-251db9ba1e36" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;int main(){
  boost::asio::io_service io_service;
  udp_server userver(io_service, 10000);
  io_service.run();
  return 0;
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;最後はmain関数。例外部分は省きました。&lt;br&gt;io_serviceってのがイベントの面倒をみるクラスです。&lt;br&gt;今回はudpserverクラスしか登録していませんが、同時にtcpserverクラスも登録して&lt;br&gt;両方の面倒を見てもらう、という使い方もできます。&lt;/p&gt;
&lt;p&gt;イベントをゴニョゴニョ！っと登録したらio_service.run()で待ち受け開始！&lt;br&gt;後は延々とUDPサーバが動き続けます。&lt;/p&gt;
&lt;p&gt;ということで、わずか50行程度でUDPサーバができちゃうわけですよ、すごい！&lt;br&gt;しかも、WindowsだのLinuxだのというOSを意識しないってのもいいですね。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/194133.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C++]右辺値参照の限界点</title><link>http://blogs.wankuma.com/izmktr/archive/2010/08/21/192477.aspx</link><pubDate>Sat, 21 Aug 2010 11:14:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2010/08/21/192477.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/192477.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2010/08/21/192477.aspx#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/192477.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/192477.aspx</trackback:ping><description>&lt;p&gt;右辺値参照を調べてわかった事。  &lt;p&gt;右辺値参照はオブジェクトのコピーをするときに&lt;br&gt;条件さえ整えば高速におこなう事を目的に作られた構文です。  &lt;p&gt;右辺値参照が役に立つのは、関数内でポインタの形で情報を持っているものに限られます。&lt;br&gt;ですから、直接値を持つ形になっているクラスには何の貢献もしません。&lt;br&gt;具体的には、以下のような例です。 &lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7dca7214-2798-4493-9683-c7dd5c9c464e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;/* 役に立つ例 */
class MyString{
  char *string;
} 

/* 役に立たない例 */
class Matrix44{
  float m[4][4];
} 
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;下の例の行列なんかは演算子オーバーロードで書ければすっきりするのですが、&lt;br&gt;実際にはそういうわけにはいきません。 &lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:775c7848-bfe7-4885-b013-b3dda901d13a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;/* こんな関数は速くならない */
Matrix44 operator +(const Matrix44 &amp;amp;in1, const Matrix44 &amp;amp;in2); 

/* 現実的な解 */
void Add(Matrix &amp;amp;out, const Matrix44 &amp;amp;in1, const Matrix44 &amp;amp;in2); 
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;右辺値参照を最初に聞いた時、こんな事ができる！と期待してました。 &lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7831db54-2451-47f0-b210-08cff19309da" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;/* 私がやりたかった事 */
auto operator +(const Matrix44 &amp;amp;in1, const Matrix44 &amp;amp;in2) -&amp;gt; Matrix44 &amp;amp;out{
  for(int x = 0; x &amp;lt; 4; x++){
    for(int y = 0; y &amp;lt; 4; y++){
      out[x][y] = in1[x][y] + in2[x][y];
    }
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;返り値を受け取る変数って、関数を呼び出した時点で&lt;br&gt;破壊されているものとみなしてもいいと思うんですよ。(例外やlongjmpは無視)&lt;br&gt;そして、その返り値を受け取る変数の参照が欲しい！！ 
&lt;p&gt;ということで名前付き返り値なんてものがあってもいいんじゃないかな～。&lt;br&gt;VBなんかが返り値は関数名と同名の変数に入れるタイプですね。 
&lt;p&gt;と思ってたら、どうやらReleaseモードでの最適化で似たような事をしてくれるらしいです。&lt;br&gt;(以下の記事のコメント欄参照)&lt;br&gt;&lt;a href="http://blogs.wankuma.com/episteme/archive/2010/08/06/192085.aspx"&gt;http://blogs.wankuma.com/episteme/archive/2010/08/06/192085.aspx&lt;/a&gt;
&lt;p&gt;…最適化してくれるのなら右辺値参照はいらない子なんじゃと思う今日この頃です。 &lt;br&gt;コピー以外に使い道はあるんでしょうかね？
&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/192477.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C++]コルーチンへの挑戦</title><link>http://blogs.wankuma.com/izmktr/archive/2010/04/28/188507.aspx</link><pubDate>Wed, 28 Apr 2010 22:59:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2010/04/28/188507.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/188507.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2010/04/28/188507.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/188507.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/188507.aspx</trackback:ping><description>&lt;p&gt;C++でコルーチンを作ってみるテストです。&lt;/p&gt; &lt;p&gt;さて、下のソースを見てください。&lt;br&gt;このFooという関数はまさにコルーチンです。&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:af674c4b-0ce9-40fd-8df4-d0bd23e0e2ab" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;#include "coroutine.h"

class Test:public Coroutine{
　int i;

public:
　bool Foo(){
　　CoroutineBegin();
　　for (i = 1; i &amp;lt;= 20; i++){
　　　printf("%d ", i);
　　　yield;
　　　if ((i % 3) == 0){
　　　　printf("fizz ");
　　　　yield;
　　　}
　　　if ((i % 5) == 0){
　　　　printf("buzz ");
　　　　yield;
　　　}
　　}
　　CoroutineEnd();
　　return true;
　}

};

int _tmain(int argc, _TCHAR* argv[])
{
　Test test;
　for (;;){
　　bool finish = test.Foo();
　　if (finish) break;
　　printf("---\n");
　}

　return 0;
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;実行結果はこんな感じになります。&lt;/p&gt;
&lt;p&gt;1 ---&lt;br&gt;2 ---&lt;br&gt;3 ---&lt;br&gt;fizz ---&lt;br&gt;4 ---&lt;br&gt;5 ---&lt;br&gt;buzz ---&lt;br&gt;6 ---&lt;br&gt;fizz ---&lt;br&gt;7 ---&lt;br&gt;8 ---&lt;br&gt;9 ---&lt;br&gt;(以下省略) 
&lt;p&gt;コルーチンのyieldが呼ばれる度にメインルーチンに戻ってハイフンと改行が出力されています。&lt;br&gt;いいですね、コルーチン！ 
&lt;p&gt;こんな素敵なコルーチンが使えるヘッダファイルが今ならもう一個ついて1980円！&lt;br&gt;じゃなくて、&lt;a href="http://izmktr.wankuma.com/201004/coroutine.h"&gt;こちら&lt;/a&gt;からダウンロードできます。 
&lt;p&gt;#あくまで使用は自己責任で
&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/188507.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[C++]ランダム大地に立つ</title><link>http://blogs.wankuma.com/izmktr/archive/2010/01/19/185168.aspx</link><pubDate>Tue, 19 Jan 2010 22:35:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2010/01/19/185168.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/185168.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2010/01/19/185168.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/185168.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/185168.aspx</trackback:ping><description>&lt;p&gt;標準のrand関数は余り使わない方がいい、というのは知っているでしょうか。&lt;br&gt;これは&lt;a href="http://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E5%90%88%E5%90%8C%E6%B3%95"&gt;線形合同法&lt;/a&gt;に起因する問題で、乱数といいつつも、結構規則正しいという特徴があります。&lt;/p&gt; &lt;p&gt;それを改良した乱数と言うとメルセンヌ・ツイスタが有名ですが、これもちょっとした問題があります。&lt;br&gt;それは、メモリの消費がかなり多い！&lt;/p&gt; &lt;p&gt;周期が2^19937 - 1 ということは、19937ビットのデータが必要なのです。&lt;br&gt;その大きさは約2.5KBですが、いくら高品質とはいえ、ちょっと量が多いですね。&lt;/p&gt; &lt;p&gt;それに、2^19937 - 1って数は6000桁以上！&lt;br&gt;宇宙の果てまで数えられる数の周期が必要な場面はそんなにないでしょう。&lt;/p&gt; &lt;p&gt;そこで、今回紹介するお手頃な乱数が、xorshift。&lt;br&gt;ソースは以下の通り。&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f597b90f-68f2-4527-83bb-087f2411d4cc" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;unsigned long xor128(){ 
  static unsigned long x=123456789,y=362436069,z=521288629,w=88675123; 
  unsigned long t; 
  t=(x^(x&amp;lt;&amp;lt;11));x=y;y=z;z=w; return( w=(w^(w&amp;gt;&amp;gt;19))^(t^(t&amp;gt;&amp;gt;8)) ); 
} 
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;これだけのソースですが、2^128 - 1という周期をもつ乱数で、たった16バイトしか消費しません。&lt;br&gt;staticで確保しているx, y, z, wの4つの値を保存しておくだけで、前回の乱数の続きから生成できるため、&lt;br&gt;シリアライズ化するのも簡単というとてもお手軽かつ便利な乱数です。&lt;/p&gt;
&lt;p&gt;なお、乱数の種(seed)ですが、x, y, z, wのすべてが0でなければどんな数でもいいです。&lt;br&gt;これは、128ビットの数値と見なすと、周期が2^128 - 1ということで、0以外の数値であれば、&lt;br&gt;循環する数列のどれかの要素になる、というわけです。&lt;/p&gt;
&lt;p&gt;そういえば、メルセンヌ・ツイスタを改良した&lt;a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index-jp.html"&gt;SFMT&lt;/a&gt;というものもあるみたいですね。&lt;br&gt;乱数は奥が深いです。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/185168.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[数学][C]直線交差点</title><link>http://blogs.wankuma.com/izmktr/archive/2009/10/14/182117.aspx</link><pubDate>Wed, 14 Oct 2009 20:44:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/10/14/182117.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/182117.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/10/14/182117.aspx#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/182117.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/182117.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/izmktr/archive/2009/10/09/181994.aspx"&gt;[数学]捻じれて縺れてこんがらかる&lt;/a&gt;の続き、計算編です。&lt;/p&gt; &lt;p&gt;まず、お互いの直線をベクトルと見なし、その外積を求めます。 &lt;br&gt;この外積は何を意味するかというと、前回の平行な面における法線となっています。  &lt;p&gt;&lt;img src="http://izmktr.wankuma.com/200910/nejire03.png"&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;この法線がわかれば、平行な面どうしの距離を計算する事が出ケイます。&lt;br&gt;それぞれの面から適当な点を１つづつ取り、bの面からaの面へ向かうベクトルを作ります。&lt;/p&gt; &lt;p&gt;&lt;img src="http://izmktr.wankuma.com/200910/nejire04.png"&gt;&lt;/p&gt; &lt;p&gt;この時、cと法線ベクトルの内積を求めれば、お互いの面の距離がわかります。&lt;br&gt;内積は、あるベクトル成分をどれだけ持っているか、という計算にも使えるわけです。&lt;/p&gt; &lt;p&gt;この辺のからくりがわからなくても、cと法線ベクトルが直角ならば、&lt;br&gt;aの面とbの面がぴったりくっついている、というのがわかればいいです。&lt;/p&gt; &lt;p&gt;ということで、こんな感じのソースになります。&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:8d2ca18e-dff0-48e5-ac18-bc234c7ff46f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;int LineHitCheck(const Vec3 &amp;amp;a1, const Vec3 &amp;amp;a2, const  Vec3 &amp;amp;b1, const Vec3 &amp;amp;b2){
  Vec3 va = a1 - a2;
  Vec3 vb = b1 - b2;
  Vec3 nv = outer(va, vb);
  Vec3 vc = a1 - b1;

  if (nv.x == 0 &amp;amp;&amp;amp; nv.y == 0 &amp;amp;&amp;amp; nv.z == 0){
    // 平行or同一の場合
    Vec3 nv2 = outer(va, vc);
    if (nv2.x == 0 &amp;amp;&amp;amp; nv2.y == 0 &amp;amp;&amp;amp; nv2.z == 0){
      return 同一;
    }else{
      return 平行;
    }
  }else{
    // 交差orねじれの場合
    if (inner(vc, nv) == 0){
      return 交差;
    }else{
      return ねじれ;
    }
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;平行だったときの場合は飛ばしましたが、直線Aと直線Bが同一ということは、&lt;br&gt;直線B上にあるすべての点が直線A上にあるということです。&lt;br&gt;ですから、直線Aの一点と直線Bの一点を結ぶベクトルは、常に直線Aベクトルと0度or180度であり、&lt;br&gt;外積を求めると必ず零ベクトルになります。&lt;/p&gt;
&lt;p&gt;ねじれの直線の距離は、法線ベクトルを正規化してcベクトルとの内積を求めると出ます。&lt;br&gt;カプセルの当たり判定で求める事があるかもしれません。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/182117.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>出水 洸太郎</dc:creator><title>[数学][C]内積と外積を軽く分析</title><link>http://blogs.wankuma.com/izmktr/archive/2009/10/14/182088.aspx</link><pubDate>Wed, 14 Oct 2009 09:55:00 GMT</pubDate><guid>http://blogs.wankuma.com/izmktr/archive/2009/10/14/182088.aspx</guid><wfw:comment>http://blogs.wankuma.com/izmktr/comments/182088.aspx</wfw:comment><comments>http://blogs.wankuma.com/izmktr/archive/2009/10/14/182088.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.wankuma.com/izmktr/comments/commentRss/182088.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/izmktr/services/trackbacks/182088.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/izmktr/archive/2009/10/09/181994.aspx"&gt;[数学]捻じれて縺れてこんがらかる&lt;/a&gt; の続きです。&lt;/p&gt; &lt;p&gt;今回は軽くおさらいです。&lt;br&gt;ベクトルを使うに当たり、三次元空間の内積、外積を解説します。&lt;/p&gt; &lt;p&gt;・内積&lt;br&gt;別名、スカラー積ともよばれ、ベクトルaとベクトルbの内積は一次元の数値となります。&lt;br&gt;要は、ベクトルじゃないよ、ってことです。&lt;/p&gt; &lt;p&gt;なお、内積が0になるときは、掛け合わせたベクトルが直交するときです。&lt;br&gt;これは二次元における内積と同じです。&lt;/p&gt; &lt;p&gt;なお、計算式は以下のようになります。&lt;br&gt;ｘ、ｙ、ｚそれぞれを掛け合わせてたします。&lt;/p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f8053fa1-eb21-4eb9-aa71-88556bc75a86" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;struct Vec3{
  int x, y, z;
};

int inner(const Vec3 &amp;amp;a, const Vec3 &amp;amp;b){
  return a.x * b.x + a.y * b.y + a.z * b.z;
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;・外積&lt;br&gt;別名、ベクトル積で、ベクトルaとベクトルbの内積はベクトルとなります。&lt;br&gt;この外積で出てくるベクトルはベクトルa、ベクトルbの両方に直交します。&lt;/p&gt;
&lt;p&gt;前を表すベクトルと、上を表すベクトルから右を表すベクトルを作り出せます。&lt;br&gt;ここで、前と上を表すベクトルは必ずしも直行しなくてよいことが重要です。&lt;/p&gt;
&lt;p&gt;なお、外積の結果が零ベクトルになることがありますが、&lt;br&gt;これは掛け合わせたベクトルが同一方向か逆方向を向いているときです。&lt;/p&gt;
&lt;p&gt;先ほどの例だと、前を表すベクトルが真上を向いてしまうと、&lt;br&gt;北極点における東方向という感じで、右方向というのが決まらなくなってしまいます。&lt;br&gt;こういう場合に零ベクトルとなるわけです。&lt;/p&gt;
&lt;p&gt;外積の計算式は以下の通りです。&lt;br&gt;x→y→z→x というローテーションを意識して、別々を掛けて引くというという形になります。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:76cda1fd-16c6-4fe2-bc99-1ba01cff78f2" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c"&gt;Vec3 outer(const Vec3 &amp;amp;a, const Vec3 &amp;amp;b){
  Vec3 c;
  c.x = a.y * b.z - a.z * b.y;
  c.y = a.z * b.x - a.x * b.z;
  c.z = a.x * b.y - a.y * b.x;
  return c;
}&lt;/pre&gt;&lt;/div&gt;&lt;img src ="http://blogs.wankuma.com/izmktr/aggbug/182088.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>