C++

2019年02月02日

以前に、C++標準で利用できるデータ構造、特にSTLのコンテナ型を使い分けることについてQiitaに書いたものを多くの方にご覧いただけていたのですが、これについて大幅加筆のうえ動画講座化したものを公開しました。

C++ STLのコンテナ型を動作効率を考えて使いこなす! | Udemy

有料講座ではありますが、一部の内容を無料でご覧いただけます。
また2月いっぱいについては、上記のリンクから辿っていただけると、購入される場合にキャンペーン価格(¥3600→¥1200)となります。※もし値引きの表示が出ていなければお問い合わせください(offkaiあっとまーくhhiro.net)。よろしければご利用ください。

【余談】
もともと動画講座化の提案を頂いたのは、上記Qiitaの内容を少しだけ含んだより広範な内容のほうだったのですが、講座としてまとまった量を書くなら上記Qiitaで扱っている「STLのコンテナ型」関連に絞ったほうがよいと思ったこと、また上記Qiitaの内容が多くの方に閲覧されているということから力を入れてまとめたいと思っていたこともあり、こちらの内容を取り扱うことにしました。

maraigue at 02:25コメント(0) 

2017年03月25日

でじぽろ#13 & 札幌C++勉強会 - connpass

3月19日(日)に開催しました。
でじぽろが開催を検討していたところに、札幌C++勉強会も加わらせていただく形で開催しました。

でじぽろとは

  • 初心者に優しく
  • 他の勉強会への踏み台
  • 発表者が話したいことを話す
を三本の柱として、
  • 「IT技術に興味はあるけど、北海道の勉強会ってよくわかんないしハードルが高い」と感じてる方や、
  • 「Linuxには触ったことがあるけど、武器にできる言語がまだない」方や、
  • 「Linuxを触ったことがないけど、興味がある」
といったレベルの方に照準を合わせて行います。

でじぽろ - connpass

もっと初心者向けな勉強会が欲しくない?ということで立ち上げられた勉強会、と聞いていました。
ということ自体は話として知っていたのですが、普段札幌にいない身としては、雰囲気を実際に感じ取ることができたのはよかったなと思いました。やっぱり、勉強会に参加しないと勉強会の…もっといえばその地域のコミュニティに対する肌感覚って得られないなあというのは感じました。
初心者でもどんどん発表していこう、という雰囲気を作っているのだなというのが感じられました。

私の発表

これまでC++勉強会ではライブラリの活用等について話すことが多かった私ですが、C++はそれを話すとどうしても込み入った話になってしまうことが多い(計算時間とかメモリとか)ため、初心者向けというでじぽろのコンセプトも考慮し、今回は「C++で〜をしたければ標準ライブラリの〜を使おう」ということを紹介していくという内容にしました。
C++を初めて使う方には他の言語の比較になるように、またC++をすでに使っている方も「知らないライブラリに出会えるかもしれない」ということを目指した内容にしました。

C++11以降ではスマートポインタ・スレッド・関数オブジェクト関連など標準化されたライブラリも増えたので、このあたりもちゃんと紹介しました。併せて、「今の最新のコンパイラならC++11の機能はだいたい使えるよ」ということも強調しておきました。



maraigue at 18:14コメント(0)トラックバック(0) 

2016年12月10日

この記事は、Kawaz Advent Calendar 2016の12/7ぶんです。Kawazのサイト内で公開されている記事と同じものです。

担当の日を勘違いして2日遅刻した。

概要

今年に入って、sapporo.cppの企画においてopenFrameworksという、ゲーム向きなマルチプラットフォームフレームワークを使い始めたのですが、そんなこともあって最近は個人的な制作物にも使い始めるようになった。
ということで、openFrameworksを使っての感想とか気づいたことを紹介するとともに、最近作ったもの「スクロールバー」を紹介する。

経緯をもう少し詳しく

昨年のKawaz Advent CalendarにてオセロAIを作ったという話を書いたのだが、こういったものをGUIで動くようにすればもっと目を引くのでは?ということで作ったのであった。

こちらで、作成した「4目並べ」を公開しています(sapporo.cppとしての制作物です)。sapporocpp/4moku: 4目並べ

使ってみての感想

  • 基本的には、よくありそうなゲーム向けフレームワークという雰囲気。
  • 割と便利だと思ったもの
    • 最小限のフォントが組み込まれている。デバッグ表示したいときとかに便利。
    • 画面表示に限らず、ファイル読み込みとかスレッドといったものに対しても、プラットフォームに依存せずコードを書くためのラッパーが提供されている。ファイルを開くとかのダイアログも提供されていたのだが、非ASCII文字が正常に扱えない(もしかしたらWindowsの場合のみ?)という問題があって利用を断念した。
  • WindowsとAndroidのマルチプラットフォームを対応したかったのですが、そもそもAndroid向けサンプルプログラムのビルドを通すことすらできず断念しました…。なお開発環境としてWindowsのほかUbuntuで試してもだめでした。
    • 結局現在は、Windows向けアプリ制作のために使っています。Visual Studioから使うのがすごく楽なので。(公式サイト内に掲載の手順に従えば簡単に動く)
  • この手のフレームワークではよくあることではありますが、グローバルな状態管理(例:描画色を指定する関数ofSetColorはグローバルに機能する)が多い。
    • 最近罠にはまったのは、ofSetColorが読み込んだ画像の描画にも適用されるということ(例えば、ofSetColorで赤を指定したら、読み込んだ画像を描画する際に赤みがかかる。元の色で表示したければofSetColor(255)を事前に呼んでおかないとならない)。

作ったもの:スクロールバー

openFrameworks向けスクロールバー

openFrameworksにスクロールバーが欲しくなって作った、というもの。
まあWindows APIを呼んで生成してもよかったのだが、他に何かに使えるかもということで自分で作ってみた。作って公開している人が他に見当たらなさそうだったし(いるのかもしれないけど)。

ソースコード/サンプルプログラムはこちら。GitHub - maraigue/ScrollBar4OF

なぜこれを作ったのか

もともとは某音楽ゲームの譜面シミュレータを作りたかったのだが、その過程でスクロールバーがないと操作しにくい、ということで作成することにした。

じゃあ何で某音楽ゲームの譜面シミュレータを作りたかったかというと、「音楽ゲームの難易度表示が妥当か機械学習的に判断したい」という構想があって、それをするためには譜面が入力できないとどうしようもない、という事情があったのである。また、(自分が作ろうとしている件の音楽ゲームについて)そういうツールを作っている人もいなさそうなのでじゃあ作ろうかな、という気持ちもあった。
これはこれで、出来上がったらどこかで記事にします。

実装のポイント
  • 座標計算は工夫した。スクロールバーは縦と横の両方を出せるようにしたかったのだが、その両者でなるべくソースコードを共通化したかったのである。そのため、
    • 縦横のスクロールバーで共通のコードについては、座標計算に縦横という概念を用いず、「スクロールバーの長さ方向の座標」「スクロールバーの幅方向の座標」というものを導入した。
    • 上記の座標と、普通の(画面表示における)縦横の座標を変換するクラスを作り、それをテンプレートの引数に与えることで、縦スクロールバー・横スクロールバーを出せるようにした。
  • 境界条件(取りうる値の最大値/最小値を超過しないか、など)は結構気を使った。
  • スクロールバー内部の状態管理を行う変数が増えてしまうのは、仕方ないとはいえ面倒だった。例えば「現在ツマミをドラッグしている途中である」とか「マウスをクリックしてから押しっぱなしにしている」とか。

(割と)汎用的に作ったつもりなので、openFrameworksで必要な方はもちろん、他のプラットフォームに対する移植もしやすいほうじゃないか…と思っています。



maraigue at 01:58コメント(0)トラックバック(0) 

2016年11月10日

Boost.勉強会 #21 札幌

開催しました。
前回が2014年5月だったので、2年半ぶりです。
今回もまた、北海道外からも多数の参加者がありました。
そして地元の方にとっても、これによってC++に対する意識、意欲が高まってくれていれば幸いです。

まとめとか

発表資料(すでに公開されているもののみ) Boost.勉強会 #21 札幌 - 資料一覧 - connpass

睦月さんがTwitter投稿をまとめてくださってました。Boost.勉強会 #21 札幌 - Togetterまとめ

私の発表

C++1zで標準化が濃厚となったライブラリ「string_view」について話しました。

2012年11月の勉強会で、私が作成したライブラリ「fundoshi.hpp」を紹介したのですが、その後になって同様のライブラリがBoostに入っていたBoost.string_ref)ことを知り、さらに2016年になって次期のC++標準規格「C++1z」(「C++17」とも)で標準化されることが有力となったため、今回紹介することにしたものです。

他の発表を簡単に紹介

ignisさん「Boost.GILではじめる画像修復 & Pythonから利用してみる」
画像修復(例:ところどころが塗りつぶされたような画像について、その部分を検出して本来あったと思われる内容を補完する)の考え方とC++による実装の話。
画像修復の基本的な考え方は、(1)画像がどのように変形させられるかを定式化し、(2)その変形を関数とみたとき、逆関数を求めて適用し画像を復元する、というものになる。ただ逆関数といっても単純に計算できなかったり、一意に値が定まらない場合もあるので、そこはもちろん何らかの対策を考えないとならない。という話がなされた。
Boost.GILでの実装についての話としては、テンプレートを活用することで画像の特性(モノクロなのかカラーなのか、など)を問わない処理が容易に書けること、また私の発表でも示した「ビュー」(文字列なら文字列、画像なら画像の一部を参照するためのクラス)がBoost.GILでも多用されていることなどが説明された。
最後に、C++で書いたコードをPythonから利用するための方法についての話。これまでにもBoost.Pythonというものはあったが、それよりも使いやすい「PyBind11」というものがあり、こちらがいいよ!ということを力説。なお名前の通り、C++11に対応したコンパイラを利用する必要がある。
redboltzさん「CppCon2016 参加報告」「急速に進化するBoost.SML」
前半は、C++の国際会議「CppCon」の参加報告。氏はこれまでにも「C++Now」という別の会議に出たことはあったものの、CppConには今回初めて参加したとのこと。CppConはC++Nowと違って、運営がプロの手によるものであり(C++Nowはコミュニティ的)、仕事の早さなどを感じたとのこと。また今回のCppConでは「ゼロオーバーヘッド抽象化」がちょくちょく扱われていたとのこと。
後半は、Boost.SMLという、コンパイル時に行える状態遷移の表現を記述する(状態遷移の表現を実行時に構築する必要がなく、バイナリに組み込まれるようにできる)ライブラリの紹介。すでにBoost.MSMというものもあったものの、こちらのほうがかなり高速とのこと。ただしC++14に対応したコンパイラが必要である。
なお、この発表に向けてredboltzさんは、Wandbox(ブラウザ上でコードを書いて実行できる)の中の人・めるぽんさんに、Boost.SMLに対応するよう依頼していたとのこと。結果、Wandboxでサンプルコードが動いていた。
Flastさん「Boost.Fusion/Phoenixのメンテナになったのでその記念的ななにか in 札幌」
メインで話されたのは、スレッドやプロセスを抽象化するライブラリについての紹介(なお、Boost.FusionやBoost.Phoenixはそういうライブラリというわけではない)。Boost.Fiber(途中で動きを止めることで複数のFiberにある処理を代わる代わる進めることができる。完全に並列で動かせるわけではない)の紹介、Boost.Process(プロセスの新規起動など)が入るかもしれないという話をされていた。また氏は「(Boost.Hanaが登場したことで)Boost.Fusion終わるのですか?」という質問を受けたとのことで、それに対し「まだサポートは続くよ」ということを話していた。
【LT】hiyohiyoさん「C++でNVMeと(*´Д`)ハァハァ 戯れていたら一年経ってた。」
NVMe(NVM express、ハードドライブを接続する際の物理インターフェイスでSSDにも適した高速規格)について。CrystalDiskMark(ストレージのデータ転送速度測定ソフト)をWindows 10 Appとして公開した話や、他者からもらったコードがDelphiで書かれていて移植に苦戦したため「ステップ実行して挙動を確かめた」という話が。
【LT】egtraさん「Visual C++コンパイラのコードの注釈機能について」
引数に _In_, _Out_ などを付けることで、意図しない挙動が発生する場合に警告を出す機能の紹介。自分で書けないこともないがなかなか大変とのこと。今回は未初期化変数の警告、nullptrの可能性がある値に対する警告、配列の添字に対する警告を出すことについて紹介されていた。


maraigue at 22:57コメント(0)トラックバック(0) 

2016年04月03日

去る3月19日(土)に、札幌C++勉強会 #11 - connpassを開催しました。

現在、主に運営をしているメンバーが札幌にいない状況ではありますが(私と@ignis_fatuusさん)、二人が時折札幌に戻るときに実施しています。その前の第10回(2015年12月26日)も、二人が帰省するタイミングを狙って計画したものでした。
※なお、「札幌やその周辺に住んでいて、C++勉強会を計画したい!」という方がいましたら歓迎ですのでご一報ください。

私の発表

名古屋に移って研究の内容が大きく変わったわけなのですが、そこで行うようになったことをテーマに話しました。

「関数の最小化」は、中学や高校を含め、数学ではよく出る問題です。これはより一般には「最適化」と呼ばれる問題にあたり、機械学習の分野でもこれは非常に重要な考え方であるという話です。

最近「ビッグデータ」などと呼ばれるように、データがたくさん手に入るようになったことから、それを分析する手段の開発も重要となっています。人間は「事例を見て、行うべき判断などを知る」という「学習」を行いますが、コンピュータ上で手段は違えど「事例を見て、行うべき判断などを知る」ということを行わせる、というのが「機械学習」です。例えば迷惑メールフィルタを作ることを例に取ると、迷惑メールになる条件を人手で記述するのではなく、ユーザの迷惑メール報告をもとに構築するのが機械学習の考え方ということになります。

機械学習の実際の計算においては、手法によって違いはありますが、簡略化して書くと以下のような手順を踏むことになります。

  • 結果(上記の例でいえば「迷惑メールであるか否か」)を表現する関数やデータ構造の形(例えば、「データを x, y としたとき、 p(x, y) = ax + by + c の形で書ける関数」)を決める。
  • 関数 p(x, y) が、すでに持ち合わせているデータ(訓練データという。上記の例でいえば「すでに報告されている迷惑メール」)からどれだけ離れているかを表す関数 f(a, b, c) を作る。
  • f(a, b, c) を最小化するような a, b, c を求め、p(x, y) に適用する。これが「訓練データをもっともよく反映した、結果を表現する関数」となる。

特に機械学習を行うという観点では、その関数 f(a, b, c) の最小化が実際に計算できないのでは、学習結果も得られないことになってしまうため、どんな関数であれば計算が容易なのか判断することは非常に大事です。詳細は資料中で解説していますが、この問題を考えるにあたって重要なキーワードとして、「極小値」や「凸関数」というものがあります。

C++のソースコードも用意しています(github: maraigue/sapporocpp-20160319)。簡単な実装ではありますが、機械学習の簡単な例である線形分類(「男性と女性」など2種類に分けられるデータ点を、2次元なら直線、3次元なら平面…で分ける最良のものを出力する)のサンプルも用意しています。



maraigue at 01:52コメント(0)トラックバック(0) 

2014年12月08日

qiitaに書きました。
C++ - std::string::findより速くなるかもしれない。boost::algorithmのboyer_moore_searchとかknuth_morris_pratt_searchとか - Qiita

この記事は、C++ Advent Calendar 2014の12月7日ぶんとして書きました。
文字列検索アルゴリズム(ここでは、二つの文字列c, pを与えて、cの部分文字列がpになるような場所を探すこと)として理論的に速いことが知られているボイヤー-ムーア法クヌース-モリス-プラット法が、C++標準のfindでは採用されておらず(Boostでは利用可能)、「これってオーバーヘッドが大きいのだろうか」ということで調べてみたくなりやってみたものです。
アルゴリズムの概要、Boostでの利用方法、実験を載せています。

maraigue at 00:52コメント(0)トラックバック(0) 

2014年09月19日

概要

Ohotech 特盛 #10 - connpass

北見市で開催されている勉強会。今回は「sapporo.cppの人たちに北見で話してもらえないか」という依頼をいただいていたことから実行に移したもので、メンバー4人が遠征。

私の発表内容

というテーマで話しました。STLには多数のコンテナ型が存在するのですが、使い分けの指針をまとめているような記事がなかったということもあり、それを意識付けられるように概観する、という目的のもと作りました。

伝わりにくい部分もあったかな…と思ったことに加え、スライド形式ではなく単なる一枚のWebページとして読める記事を書いておきたかったこともあり、後日改めてまとめました。→ [C++] STLの型の使い分け - Qiita

【2014.10.23追記】 10月18日の札幌C++勉強会 #7にて、上記Qiitaの記事のダイジェスト版を発表しました。

他の方の発表内容

公開されているもののみ

C++ マルチスレッドプログラミング(hotwatermorningさん)

旅行記

初日。早朝から車移動。
白滝パーキングエリアで休憩。ゆでたてのとうきび(とうもろこし)が食べられた。
白滝パーキングエリア
ゆでたてのとうきび

北見の会場到着。
Ohotech会場の掲示

会場の目の前で「北見地産地消フェスタ2014」なるイベントが開かれていたので昼食。地元の産物を使った食べ物を楽しむ。
芋ピザ
ホットドッグ

Ohotechの会場風景
Ohotech会場
おやつ

懇親会は焼肉。ちなみに北見は焼肉屋が非常に多いことで知られる
懇親会会場
焼肉

翌日。ホテルで朝食をとって出発。
朝食

道の駅「ぐるっとパノラマ美幌峠」。南側は屈斜路湖、北側は丘陵の森と草原を眺められる。
道の駅
美幌峠から南側(屈斜路湖)を見る
美幌峠から北側を見る

摩周湖
看板
摩周湖
摩周岳
↓奥の頂上が隠れている山はおそらく斜里岳
摩周湖。奥の頂上が隠れている山はおそらく斜里岳
↓摩周湖の色をイメージしたブルーソフト
摩周湖ブルーソフト

帯広で豚丼(BUTA DON CAFE 創)。3種の肉の部位が入っていたのだが、いずれもおいしくいただいた。ほうじ茶で炊いたご飯が特徴的。
豚丼カフェ「創」
豚丼



maraigue at 03:04コメント(0)トラックバック(0) 

2014年08月12日

はじめに

この内容は、7月12日の7/12 プログラミング生放送 + CLR/H + Sapporo.cpp 勉強会@札幌の参加記録と、そこで発表したものの補遺(完全版)です。

この日の発表の時点では、「最小乗車距離でJR線全線を乗り尽くして出発駅まで戻る」問題をJR北海道を対象として解くことはできたものの、JR全線を対象に解くのは問題の大きさゆえ不可能でした。そのため改良版の制作に取り組んでおり、このたび完成した(おそらく)ので発表するものです。

勉強会について

プログラミング生放送という、ニコ生で配信される勉強会である。札幌では2年前に開催された以来の開催で、今回もCLR/Hならびにsapporo.cppとの共催となった。私はsapporo.cppの一員として参戦した。

Twitterまとめはこちら(私のまとめではありません)

会場 おやつ

また、札幌で痛タクシーを走らせている長栄交通様の協力で、プロ生ちゃん(暮井慧)タクシーが実現することに。

プロ生ちゃんタクシー プロ生ちゃんタクシー プロ生ちゃんタクシー プロ生ちゃんタクシー プロ生ちゃんタクシー

内容

ソースコードはこちらに公開しています。maraigue/cpp-chinese-postman (github)

詳細、ならびにアルゴリズムの概要はこちらのスライドに掲載しています。

問題設定の要約は以下の通りになります。「中国人郵便配達問題」という名前が付いています。

  • 「JR線全線を乗り尽くして出発駅まで戻る」ことを、最短の乗車距離で行う。
  • JR以外の交通機関は使わないものとする。
  • 「札幌-白石間の函館本線・千歳線並走区間」のように、路線が分かれていても営業上同一となる区間については、同一の路線と扱う(どれか1路線乗ればよい)とする。ただし、ミニ新幹線を除く新幹線に限っては別路線と扱う。
続きを読む

maraigue at 01:27コメント(0)トラックバック(0) 

2014年07月09日

追記(2016.7.26):C++1z(C++17)にて、「string_view」という名前で標準化される見込みとのことです。
C++17 Fundamentals
maraigue/fundoshi.hpp
以前公開した「文字列から部分文字列を取得する際、ポインタのみを受け渡すことでメモリ消費を抑える(ただし、元の文字列が変更されると部分文字列のほうも変更される)」というライブラリ。

2011年に制作してgist.githubに公開し、2012年5月に正式公開したのだが、
その一方で、これと同等の用途のライブラリが、C++の一大ライブラリ(特に、標準規格化を目指す機能が多数集まるライブラリ)のBoostに搭載されていることを、つい今知ったのである。
String_Ref - 1.55.0(公式リファレンス、英語)
boost::string_ref - Faith and Brave - C++で遊ぼう

調べてみると、これがBoostに採用されたのは2013年2月公開のバージョン1.53.0で、2012年9月にC++の新標準案として提起されたものを実装したものとのことである。

大手のライブラリに自分が欲しかった機能が乗る(しかも標準化も目指されている)というのは嬉しいことですが、その一方で、自分で作ったほうのライブラリをどうしようか、と思っている状況です。ライブラリ作者の宿命というかなんというか。

maraigue at 00:43コメント(0)トラックバック(0) 

2014年07月07日

【この記事を書いたきっかけ】

  • std::map::atの存在を知って感激した
  • ただ、その意義から詳しく説明している記事が見当たらなかった

【解説】

実際にやりたかったのは以下のコードのようなこと。
「クラスのメンバ変数にstd::mapがあって、それを内容を変更しないという条件のもとでクラス外部から自由に触れるようにしたい」(つまり、値の取得や検索が自由にできる)というものである。

#include <map>

class MyClass{
public:
    typedef std::map<int, int> storage_type;
    
private:
    storage_type value_;
    
public:
    MyClass(){
        // ここは適当。実際は別の入力(ファイルの内容とか)に基づき
        // 何らかの値をvalue_に格納する
        value_[3] = 5;
        value_[5] = 10;
        value_[8] = 15;
    }
    
    // ここでstd::mapへのconst参照を返す
    const storage_type & value() const{
        return value_;
    }
};

MyClassのメンバ変数 value_ の内容を変更されないように、MyClassから value_ を渡すときはconst参照で返すようにしているのだが、その参照からキーを指定して要素を取得する際、 myc.value()[key] のようにアクセスするとコンパイルエラーになる。
これはstd::mapの[]は「指定されたキーの要素が存在しなければ新規に生成する」という挙動であり、constなメソッドでない(=インスタンスの内容を変更する可能性がある)ためである。

これを回避するための方法として、mapのメンバ関数「find」を用いるというものがある。ただこれは値の取り出しのために一度イテレータ型を定義したりしないとならないなど、記法の面で何かと面倒なのである。

// std::cout << myc.value()[8] << std::endl;
// ↑これはコンパイルエラー。myc.value()が示す参照の先を書き換えかねないため

MyClass::storage_type::const_iterator it;

it = myc.value().find(8);
std::cout << (it != myc.value().end() ? it->second : -1) << std::endl;
// ↑値が見つかるので「15」と表示

it = myc.value().find(10);
std::cout << (it != myc.value().end() ? it->second : -1) << std::endl;
// ↑値が見つからないので「-1」と表示

ということで困っていていろいろ調べていたら、C++11では「at」メソッドが新設されたことを把握した。機能としてはstd::vectorのatと類似している。すでにmap内に存在している値を取り出したり書き換えることに特化したもので、[]と異なり、キーが存在しなければ例外 std::out_of_range を発生するようになっている。
なおatメソッドはすでにmap内に存在している値を「書き換える」ことができると上に書いたが、atメソッドは実際、単なる参照を返すものとconst参照を返すものがオーバーロードで存在し、前者であれば値を書き換えることができるが後者ではできないようになっている。なおmap自体がconst参照で与えられている場合は、当然後者しか利用することができなくなっている。

try{
    std::cout << myc.value().at(8) << std::endl;
    // ↑値が見つかる。見つからなかった場合にcatch以降の部分が実行される
}catch(const std::out_of_range & e){
    std::cout << "Not Found" << std::endl;
}

なお、gccにおいてはすでにバージョン4.1.1の時点で独自拡張としてatメソッドが存在していたとのこと。なのでC++11の機能を利用する際に必要なgccのオプション「-std=c++0x」や「-std=c++11」がなくてもatメソッドは利用できる。

サンプルコードはこちら。

【参考記事】



maraigue at 23:22コメント(0)トラックバック(0) 
livedoor プロフィール

H. Hiro

  • ライブドアブログ