Submit Search
Upload
拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った
•
2 likes
•
2,307 views
D
digitalghost
Follow
printfとstd::basic_ostreamとboost::formatが合わさり一見最強に見える出力フォーマットライブラリを作ったという話
Read less
Read more
Technology
Report
Share
Report
Share
1 of 21
Download now
Download to read offline
Recommended
お前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのか
Kousuke Ebihara
C++11概要 ライブラリ編
C++11概要 ライブラリ編
egtra
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
勝成 鈴江
Map
Map
kikairoya
templateとautoの型推論
templateとautoの型推論
MITSUNARI Shigeo
C++ Template Metaprogramming
C++ Template Metaprogramming
Akira Takahashi
2018年度 若手技術者向け講座 リファクタリング
2018年度 若手技術者向け講座 リファクタリング
keki3
Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理
Takuya Tsuchida
Recommended
お前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのか
Kousuke Ebihara
C++11概要 ライブラリ編
C++11概要 ライブラリ編
egtra
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
勝成 鈴江
Map
Map
kikairoya
templateとautoの型推論
templateとautoの型推論
MITSUNARI Shigeo
C++ Template Metaprogramming
C++ Template Metaprogramming
Akira Takahashi
2018年度 若手技術者向け講座 リファクタリング
2018年度 若手技術者向け講座 リファクタリング
keki3
Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理
Takuya Tsuchida
C++0x in programming competition
C++0x in programming competition
yak1ex
C++0x in programming competition
C++0x in programming competition
yak1ex
Boost tour 1_44_0
Boost tour 1_44_0
Akira Takahashi
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
Hiro H.
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
Preferred Networks
C++によるソート入門
C++によるソート入門
AimingStudy
Python standard 2022 Spring
Python standard 2022 Spring
anyakichi
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
Hiro H.
Learning Template Library Design using Boost.Geomtry
Learning Template Library Design using Boost.Geomtry
Akira Takahashi
Write good parser in perl
Write good parser in perl
Jiro Nishiguchi
プログラミングで言いたい聞きたいこと集
プログラミングで言いたい聞きたいこと集
tecopark
プログラミングで言いたいこと聞きたいこと集
プログラミングで言いたいこと聞きたいこと集
tecopark
初めてのSTL
初めてのSTL
HCPC: 北海道大学競技プログラミングサークル
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
cp-11. ポインタ
cp-11. ポインタ
kunihikokaneko1
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
Akira Takahashi
ぼくのかんがえたさいきょうのついったーくらいあんと
ぼくのかんがえたさいきょうのついったーくらいあんと
Yutaka Tsumori
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
TATSUYA HAYAMIZU
Boost.B-tree introduction
Boost.B-tree introduction
Takayuki Goto
C++0x 言語の未来を語る
C++0x 言語の未来を語る
Akira Takahashi
ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体
digitalghost
Define and expansion of cpp macro
Define and expansion of cpp macro
digitalghost
More Related Content
Similar to 拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った
C++0x in programming competition
C++0x in programming competition
yak1ex
C++0x in programming competition
C++0x in programming competition
yak1ex
Boost tour 1_44_0
Boost tour 1_44_0
Akira Takahashi
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
Hiro H.
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
Preferred Networks
C++によるソート入門
C++によるソート入門
AimingStudy
Python standard 2022 Spring
Python standard 2022 Spring
anyakichi
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
Hiro H.
Learning Template Library Design using Boost.Geomtry
Learning Template Library Design using Boost.Geomtry
Akira Takahashi
Write good parser in perl
Write good parser in perl
Jiro Nishiguchi
プログラミングで言いたい聞きたいこと集
プログラミングで言いたい聞きたいこと集
tecopark
プログラミングで言いたいこと聞きたいこと集
プログラミングで言いたいこと聞きたいこと集
tecopark
初めてのSTL
初めてのSTL
HCPC: 北海道大学競技プログラミングサークル
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
cp-11. ポインタ
cp-11. ポインタ
kunihikokaneko1
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
Akira Takahashi
ぼくのかんがえたさいきょうのついったーくらいあんと
ぼくのかんがえたさいきょうのついったーくらいあんと
Yutaka Tsumori
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
TATSUYA HAYAMIZU
Boost.B-tree introduction
Boost.B-tree introduction
Takayuki Goto
C++0x 言語の未来を語る
C++0x 言語の未来を語る
Akira Takahashi
Similar to 拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った
(20)
C++0x in programming competition
C++0x in programming competition
C++0x in programming competition
C++0x in programming competition
Boost tour 1_44_0
Boost tour 1_44_0
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
C++によるソート入門
C++によるソート入門
Python standard 2022 Spring
Python standard 2022 Spring
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
Learning Template Library Design using Boost.Geomtry
Learning Template Library Design using Boost.Geomtry
Write good parser in perl
Write good parser in perl
プログラミングで言いたい聞きたいこと集
プログラミングで言いたい聞きたいこと集
プログラミングで言いたいこと聞きたいこと集
プログラミングで言いたいこと聞きたいこと集
初めてのSTL
初めてのSTL
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
cp-11. ポインタ
cp-11. ポインタ
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
ぼくのかんがえたさいきょうのついったーくらいあんと
ぼくのかんがえたさいきょうのついったーくらいあんと
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
Boost.B-tree introduction
Boost.B-tree introduction
C++0x 言語の未来を語る
C++0x 言語の未来を語る
More from digitalghost
ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体
digitalghost
Define and expansion of cpp macro
Define and expansion of cpp macro
digitalghost
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
digitalghost
君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない
digitalghost
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みください
digitalghost
No skk, no life.
No skk, no life.
digitalghost
Boost.Preprocessorでプログラミングしましょう
Boost.Preprocessorでプログラミングしましょう
digitalghost
テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式
digitalghost
Preprocess-time Lambda Expression
Preprocess-time Lambda Expression
digitalghost
More from digitalghost
(9)
ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体
Define and expansion of cpp macro
Define and expansion of cpp macro
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みください
No skk, no life.
No skk, no life.
Boost.Preprocessorでプログラミングしましょう
Boost.Preprocessorでプログラミングしましょう
テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式
Preprocess-time Lambda Expression
Preprocess-time Lambda Expression
拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った
1.
値をフォーマットして 出力してますか
2.
printf printf(“%3dn%3dn”, 42,
123); ● 42 123 ● 文字列の中に細かい出力制御を含めて書けるので割と便利 ● 組み込み型限定 ● フォーマット文字列と引数の整合性が取れてるか分からない (最近のコンパイラなら独自拡張で分かるかもしれない)
3.
IOStream std::cout <<
std::setw(3) << 42 << 'n' << 123 << 'n'; ● ユーザ定義型でも組み込み型と同じように出力 できるしフォーマットの細かい制御もできる ● マニピュレータはクソ面倒
4.
Boost.Format cout <<
boost::format(“%1%n%2%n”) % 42 % 123); ● ユーザ定義型に対しても使えるが細かいフォー マット制御は指定できない
5.
拡張可能でprintfっぽい書式指定ができて書式 指定文字列と引数をコンパイル時に検証できる文 字列フォーマット関数を作った
2014/09/20 Boost.勉強会#16 大阪 https://twitter.com/decimalbloat
6.
拡張可能でprintfっぽい書式指定ができて書式 指定文字列と引数をコンパイル時に検証できる文 字列フォーマット関数を作ってる
2014/09/20 Boost.勉強会#16 大阪 https://twitter.com/decimalbloat
7.
細かいところの実装が間に合ってない
8.
Desalt.Format ● http://github.com/dechimal/desalt
● printfっぽく書式を指定できて ● ユーザ定義型に使えて ● 書式指定文字列をコンパイル時に検証できる
9.
すごい!
10.
使い方 DESALT_FORMAT_PRINT(“%3dn%3d”, 42,
123) ● printfとだいたい同じ ● 最初の引数にはコンパイル時に評価される文字列のみ使える ● デフォルトでは組み込みの数値型と basic_ostream<CharT, Traits> ost について ost << x; が定義されている型に対して使える – ただし浮動小数点数型は現在未実装 – あとなんか忘れてるものもあるかもしれない
11.
コンパイル時にエラーを検出 DESALT_FORMAT_PRINT(“%d%”, 42);
● 42% のつもり ● static_assertで失敗する
12.
ユーザ定義型に対して拡張する DESALT_FORMAT_PRINT(“%hoge %d”,
my_int{42}, 123); ● my_intはhoge指定子で2倍の値を出力すると する
13.
こんな感じで作る struct my_int
{ int a; }; namespace desalt { namespace format { namespace traits { template<char const * String, std::size_t I, std::size_t E> struct argument_formatter<String, I, E, my_int> { static_assert(E - I >= 4, ""); static_assert(*(String + I + 0) == 'h' && *(String + I + 1) == 'o', ""); static_assert(*(String + I + 2) == 'g' && *(String + I + 3) == 'e', ""); static constexpr std::size_t end_pos = I + 4; static constexpr std::size_t used_indexes_count = 0; template<typename ...Args> static void format(std::ostream & ost, my_int i, Args const & ...) { ost << i.a * 2; } }; }}} ● String は書式文字列,I はString中の my_int の書式の開始位置, E は長さ
14.
こんな感じで作る struct my_int
{ int a; }; namespace desalt { namespace format { namespace traits { template<char const * String, std::size_t I, std::size_t E> struct argument_formatter<String, I, E, my_int> { static_assert(E - I >= 4, ""); static_assert(*(String + I + 0) == 'h' && *(String + I + 1) == 'o', ""); static_assert(*(String + I + 2) == 'g' && *(String + I + 3) == 'e', ""); static constexpr std::size_t end_pos = I + 4; static constexpr std::size_t used_indexes_count = 0; template<typename ...Args> static void format(std::ostream & ost, my_int i, Args const & ...) { ost << i.a * 2; } }; }}} ● end_pos は my_int の書式指定子の終端の位置
15.
こんな感じで作る struct my_int
{ int a; }; namespace desalt { namespace format { namespace traits { template<char const * String, std::size_t I, std::size_t E> struct argument_formatter<String, I, E, my_int> { static_assert(E - I >= 4, ""); static_assert(*(String + I + 0) == 'h' && *(String + I + 1) == 'o', ""); static_assert(*(String + I + 2) == 'g' && *(String + I + 3) == 'e', ""); static constexpr std::size_t end_pos = I + 4; static constexpr std::size_t used_indexes_count = 0; template<typename ...Args> static void format(std::ostream & ost, my_int i, Args const & ...) { ost << i.a * 2; } }; }}} ● used_indexes_count はこのformatが消費した引数の数(詳細は後述)
16.
こんな感じで作る struct my_int
{ int a; }; namespace desalt { namespace format { namespace traits { template<char const * String, std::size_t I, std::size_t E> struct argument_formatter<String, I, E, my_int> { static_assert(E - I >= 4, ""); static_assert(*(String + I + 0) == 'h' && *(String + I + 1) == 'o', ""); static_assert(*(String + I + 2) == 'g' && *(String + I + 3) == 'e', ""); static constexpr std::size_t end_pos = I + 4; static constexpr std::size_t used_indexes_count = 0; template<typename ...Args> static void format(std::ostream & ost, my_int i, Args const & ...) { ost << i.a * 2; } }; }}} ● format は実際の処理を行う関数
17.
こんな感じで作る struct my_int
{ int a; }; namespace desalt { namespace format { namespace traits { template<char const * String, std::size_t I, std::size_t E> struct argument_formatter<String, I, E, my_int> { static_assert(E - I >= 4, ""); static_assert(*(String + I + 0) == 'h' && *(String + I + 1) == 'o', ""); static_assert(*(String + I + 2) == 'g' && *(String + I + 3) == 'e', ""); static constexpr std::size_t end_pos = I + 4; static constexpr std::size_t used_indexes_count = 0; template<typename ...Args> static void format(std::ostream & ost, my_int i, Args const & ...) { ost << i.a * 2; } }; }}} ● ost は出力先,i は出力する値,Args ... は引数リスト全体(詳細は後述)
18.
ややこしい機能 printf(“%2$d, %1$d”,
42, 123) ● 123, 42 ● 位置指定 ● 特に何もしなくてもできる
19.
ややこしい機能 printf(“%0*d %d”,
42, 3, 123) ● 042 123 ● 表示したい引数以外に使いたい引数がある ● used_indexes_countに使った数を指定する ● format関数に渡された引数リストから拾って くる
20.
予定 ● printfの持つ書式指定子のほとんど
● コンテナとかに対するデフォルト実装
21.
終わり
Download now