ROS 2時代のC++11,14
ROS 2では、C++はC++11とC++14の一部、PythonはPython 3.5以上が採用されることになりました。 C++に関しては、C++17の正式リリースが済んで開発環境も整い次第、こちらも採用するという意欲的な態度を取っています。
そのため、ROS 2ユーザはC++03のこれまでのプログラミングスタイルから脱却する必要があります。 本日は、ROS 2のソースコードを読んでいて頻出するC++11, 14の言語仕様を列挙します。
参考文献
C++11, 14に関する書籍では、O'ReillyのEffective Modern C++が一番実践的な内容にまとまっていました。
オライリージャパン
売り上げランキング: 21,157
その他、ウェブサイトでは以下のサイトがすべての言語機能を紹介していて、C++11の追加言語機能の多さに驚かされます。
autoキーワード
変数宣言時に具体的な型名の代わりにauto
を指定することで、変数の型を初期化しから推論します。
auto i = 0;
auto result = some_method(1, 2, 3);
関数の返り値であったり、テンプレートを使ったときにコーディング量が減って効果を発揮します。 ただし、あまり多用するとソースコードを読む自分以外の人が何をやっているのか、意味を読み取るのが難しくなるので、ご注意を。
decltype
オペランドで指定した型を取得することができます。
int i = 0;
decltype(i) j = 1;
上記例ではdecltype(i)
がコンパイル時にint
に置き換わります。 auto
と同様に、多用するとソースコードのリーダビリティを下げる可能性があります。
lambda式
関数オブジェクトをその場で定義します。 ROS 2のSubscriberのコールバック関数呼び出しに使うと便利です。
auto subscriber = this->create_subscription<:msg::int32>(
input, [](std_msgs::msg::Int32::SharedPtr msg) {
// Do something
}, rmw_qos_profile_default);
[]
の部分をキャプチャと呼び、説明は省きますが、関数の外の変数へのアクセス方法を制御します。
std::unique_ptr, std::shared_ptr
リソースへのポインタの所有権を占有するものがunique_ptr
、共有するものがshared_ptr
です。 スマートポインタとも呼ばれます。 同じくC++11で導入されたムーブセマンティクスを組み合わせることで、C++98のauto_ptr
が抱えていた問題を解決しました。
auto node1 = std::shared_ptr(new rclcpp::node::Node("some_node"));
auto node2 = rclcpp::node::Node::make_shared("some_node");
上記node1
とnode2
は、結果としてrclcpp::node::Node
へのポインタを所有しているという意味では同じですが、メモリ割り当ての効率から、後者が推奨されています。
ROS 1でもBoostライブラリの同名の似た機能boost::shared_ptr
を使って代用していましたが、完全に置き換わりました。
前述のstd_msgs::msg::Int32::SharedPtr
のように、.msg
のIDLで定義したメッセージは、ビルドするとメッセージ名::SharedPtr
のshared_ptr
がエイリアスとして定義されます。
次回
今回は閑話休題的な話でしたが、これらの言語機能が読めれば、基本ROS 2のrclcpp
を使ったソースコードは読めるようになります。
明日からは、Turtlebot 2のROS 2対応版のソースコードを読みつつ、ラズパイマウスのROS 2対応を進めていきます。
Comments powered by Disqus.