C++ の std::tuple で動的にループする
たまに C++ を書かないと忘れるので…。
[コード]
#include <tuple> #include <iostream> #include <string> template<typename F, typename T, std::size_t I> void apply_impl(F f, T const& t){ f(std::get<I>(t)); } template<typename F, typename T, std::size_t ...Indices> void apply_impl(F f, T const& t, std::size_t n, std::index_sequence<Indices...>){ ((void (*[sizeof...(Indices)])(F, T const&)){apply_impl<F, T, Indices>...})[n](f, t); } template<typename F, typename ...Args> void apply(F f, std::tuple<Args...> const& t, std::size_t n){ apply_impl(f, t, n, std::index_sequence_for<Args...>()); } template<typename F, typename ...Args> void for_each(std::tuple<Args...> const& t, F f){ for(std::size_t i = 0 ; i < sizeof...(Args) ; ++i){ apply(f, t, i); } } int main(){ using namespace std::literals; auto data = std::tuple(1, 3.14, "homu"s); auto print = [](auto it){ std::cout << it << std::endl; }; apply(print, data, 0); apply(print, data, 1); apply(print, data, 2); for_each(data, [](auto it){ std::cout << it + it << std::endl; }); return 0; }
[出力]
1 3.14 homu 2 6.28 homuhomu
参考にしたコードはこのあたり。
動的に要素にはアクセスしているけど、値を返すことは出来ないので多相ラムダを渡して、それに値を渡すようにしています。
まー、実際 for_each
だけなら std::apply
とか使ったほうがよさそう。
#include <tuple> #include <iostream> #include <string> template<typename F, typename ...Args> void for_each(std::tuple<Args...> const& t, F f){ std::apply([&](auto... args) constexpr{ (f(args), ...); }, t); } int main(){ using namespace std::literals; auto data = std::tuple(1, 3.14, "homu"s); for_each(data, [](auto it){ std::cout << it + it << std::endl; }); return 0; } /* 2 6.28 homuhomu */
第8回 学生エンジニア限定LT大会!!! でエモい話をしてきた
前回に懲りずに学生に混ざってLTしてきました。
9年間ブログを書き続けて得たもの
https://osyo-manga.github.io/slide-gakusei_LT-08-9years-blog/#/
内容は『アウトプットすることで自分にもプラスになるんやで』みたいな事を話してきました。
まあ、アウトプットすることは大事なんですけど、自分にも役に立つのでいいですよねー。
皆さん、どんどんアウトプットしていきましょう。
本日のハイライト
懇親会で LT をしているあいだにピザと寿司が全部食べれられてしまっていた。
ゆるさん。
今度参加したときは2倍食べてやる!!!
表参道.rb #31 で LINE でお天気bot をつくった話をしてきた
LT してきました。
今回もご飯がとても美味しすぎた…。
LINE でお天気bot をつくった話
https://osyo-manga.github.io/slide-omotesandorb-31-otenki-bot/index.html#/
と、いうことで今回は珍しく生産性のある話をしてきました。
年末に LINE でお天気 bot を作ったので、それで利用した API や Ruboty の紹介なんかをしてきました。
Ruboty のプラグインとして LINE のアダプタとお天気 bot のハンドラをつくったので API キーさえ用意してもらえればすぐに使える(はず…。
何か問題があれば Issues まで教えてください。
そんな感じで今回で5回目のLTをしてきましたー。
運営の方々、発表を聞いてくださった皆様、ありがとうございました。
今回はちょっと参加人数が少なくていつもとは違う趣向でしたが、これぐらいの人数のほうがみんなで色々と意見をいいながら話せるのでこれはこれでよかったかな?と思いました。
みんなでワイワイいいながらコードを見るのは楽しいですね!
そろそろ話すのにも慣れていきたい。
Ruby で (a ==1 && a== 2 && a==3) の結果を真にする
と、いうのが JavaScript 界隈で流行っているので Ruby でもやってみた
==
メソッドを定義する
多分一番簡単なやり方。 比較演算子そのものの結果を変えます。
a = Object.new def a.== other true end p a == 1 && a == 2 && a == 3 # => true
a
メソッドを定義する
Ruby ではメソッド呼び出しの際に ()
を省略する事が出来るので a()
というメソッド呼び出しを a
とだけで呼び出すことが出来ます。
def a @a = (@a || 0) + 1 end p a == 1 && a == 2 && a == 3 # => true
こっちは Ruby らしいですね。
おまけ:==
ではなくて ===
を使う
主題からは外れますが Ruby では ===
演算子は特別な呼び出しなので ==
の変わりに ===
を使うといろいろな手段が使えます。
Proc#===
を使う
Proc#===
は Proc#call
と同じなのでブロックの中身をそのまま返します。
a = proc { true } # a.call 1 と同じ p a === 1 && a === 2 && a === 3 # => true
Method#===
を使う
Method#===
も Proc#===
と同様に #call
を呼び出します。
a = [1, 2, 3].method(:include?) # [1, 2, 3].include? 1 を呼び出しているのと同じ p a === 1 && a === 2 && a === 3 # => true
Range#===
を使う
Range#===
は Range#include?
を呼び出します。
a = (1..3) # (1..3).include? 1 を呼び出しているのと同じ p a === 1 && a === 2 && a === 3 # => true
Set#===
を使う
Range
と同様に Set#===
も Set#include?
を呼び出します。
require "set" a = Set[1, 2, 3] # Set[1, 2, 3].include? 1 を呼び出しているのと同じ p a === 1 && a === 2 && a === 3 # => true
Ruby たのしい
Ubuntu で Dropbox の同期が出来なかったときの対処方法
Ruby の Hash のキーを Symbol に変更する
Ruby の Hash のキーを Symbol に変更したい場合、Ruby 2.5 で追加された Hash#transform_keys
を使うとよさそう。
hash = { "name" => "homu", "age" => 14 }.transform_keys(&:to_sym) # => {:name=>"homu", :age=>14}
こういうのをやりたいことは稀によくあるのでメソッド1つで出来るのはよさそう。
ただ、#transform_keys
って名前がちょっと長いので transform_keys(&:to_sym)
を呼び出すヘルパメソッドが欲しくなる。
ちなみに Hash#transform_keys!
だと自身を破壊的に変更します。