C++ Advent Calendar 2015
をテンプレートにして作成
Check
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
&size(30){&color(darkblue,#c0c0ff){''C++(14) Enumerateユ...
#counter
*はじめに [#x761471e]
[[C++AdventCalender2015>http://www.adventar.org/calendars...
21日目の記事は、Yuki Maria Miyatakeさんによる[[boost.Asio...
23日目の記事は、on_origami さんによる[[MATLABとC++の奇妙...
Advent Calendarに参加するのも今年で4年目になりました。~
ゲームプログラミングにC++11を導入して約2年半あまり。最近...
痒いところに手がとどくようになってきたC++14ですが、便利に...
そこで、以前から自前で作成していたenumerateツールをC++14...
12/25加筆~
プログラムにミスがありました。VisualStudio以外でエラーに...
3-4 EnumAdapterの実装の22行目~
#sh(cpp){{
- return Pred::comp(toFlag(src.get<E>()), flags_);
+ return Pred::comp(toFlag(src.template get<E>()), flag...
}}
-----
* もくじ [#md950fd7]
- [[Chapter-1 enumの走査を便利にする>#w3909b06]]
--[[1-1 enumrateの走査>#f1d8f37b]]
--[[1-2 EnumListの定義>#f1d8f37b]]
- [[Chapter-2 enumをフラグとして使いたい>#w3909b06]]
--[[2-1 従来の方法の問題点>#f1d8f37b]]
--[[2-2 EnumListを利用したenumerateのフラグ化>#ve9131f4]]
--[[2-3 EnumList::Flagsの実装>#ve9131f4]]
- [[Chapter-3 enumをboost::adaptorsから使いたい>#w3909b06]]
--[[3-1 boost adaptorsでenumを便利に使う>#i3ccf435]]
--[[3-3 構造体のメンバ変数を型から取得するためのgetter定...
--[[3-4 EnumAdapterの実装>#m3f00e59]]
- [[おわりに>#end]]
-----
* Chapter-1 enumの走査を便利にする[#w3909b06]
** 1-1 enumrateの走査 [#f1d8f37b]
国籍を表すenumerate定義
#sh(cpp){{
enum class Nationality {
Japanese, // 日本
American, // アメリカ
German, // ドイツ
French, // フランス
Russian, // ロシア
};
}}
すべてのNationalityを走査するには?
#sh(cpp){{
for (int n = 0; n <= static_cast<int>(Nationality:: Russi...
auto nationality = static_cast<Nationality>(n);
hoge(nationality); // Natioanlityを使用した処理
}
}}
static_castが''冗長でイヤ''ですね
こんな風に書けたら便利です~
#sh(cpp){{
NationalityList::eachEnum([](auto nationality) {
hoge(nationality); // Natioanlityを使用した処理
});
}}
EnumListというヘルパークラスを作りました
#sh(cpp){{
using NationalityList = EnumList<Nationality, Nationality...
}}
これでOK~
終端を定義するために、列挙体の最後に'End'を追加してありま...
#sh(cpp){{
enum class Nationality {
Japanese, // 日本
American, // アメリカ
German, // ドイツ
French, // フランス
Russian, // ロシア
End, // end of Nationality
};
}}
利用制限として、値が1ずつ増えることと、既存の定義に含まれ...
** 1-2 EnumListの定義 [#f1d8f37b]
#sh(cpp){{
// enumの定義をフラグ化およびスキャンするユーティリティ
template <typename E, E Last, int FirstEnum = 0>
struct EnumList {
using value_type = typename std::underlying_type<...
static const int First = FirstEnum;
static const int Count = static_cast<int>(Last) -...
// enumを[First,Last)でなめる
template <typename Proc>
static void eachEnum(Proc proc) {
for (value_type n = First; n < static_cast<va...
proc(static_cast<E>(n));
}
}
}}
これで、EnumList<First,Last>::eachEnum(Proc)という書式で...
* Chapter-2 enumをフラグとして使いたい [#w3909b06]
** 2-1 従来の方法の問題点 [#f1d8f37b]
フラグの定義はいにしえのCの時代から大きく変化していません...
#defineをenumもしくはconst intに置き換えた程度で、使い勝...
国情報のフラグ化の例
#sh(cpp){{
enum class NationalityBitFlags {
Japanese = 1 << 0, // 日本
American = 1 << 1, // アメリカ
German = 1 << 2, // ドイツ
French = 1 << 3, // フランス
Russian = 1 << 4, // ロシア
};
}}
国籍のフラグに日本が含まれているか否かをチェックする関数...
#sh(cpp){{
bool isJapanese(NationalityBitFlags n) {
return (static_cast<int>(n) & static_cast<int>(Nationali...
}
}}
''static_castが冗長でイヤですね''
さらに条件が少し複雑(ヨーロッパ限定)になると、
#sh(cpp){{
bool isEuropean(Nationality n) {
return (static_cast<int>(n) & (
static_cast<int>(Nationality::German)|
static_cast<int>(Nationality::French)|
static_cast<int>(Nationality::Russian)) != 0;
}
}}
''とてもイヤな感じですね''
いまどきのC++でこんなコードは書きたくないです!~
**2-2 EnumListを利用したenumerateのフラグ化 [#ve9131f4]
先ほどのEnumListクラスにフラグを扱うクラスを追加して、以...
#sh(cpp){{
using NationalityFlags = EnumList<Nationality, Nationalit...
// 日本人か?
bool isJapanese(Nationality n) {
return NationalityFlags(n)(Nationality::Japanese);
}
// ヨーロッパ人か?
bool isEuropean(Nationality n) {
return NationalityFlags(n)(Nationality::German | Nationa...
}
}}
スッキリしました。enumの値を|で結合して簡単に比較ができま...
フラグがセットされているものだけ走査することもできます
#sh(cpp){{
NationalityFlags euro(Nationality::German | Nationality::...
euro.eachEnum([](auto nationality) {
hoge(nationality); // ドイツ、フランス、ロシアが実行...
});
}}
**2-3 EnumList::Flagsの実装 [#ve9131f4]
EnumListにFlagsというクラスを追加しました
#sh(cpp){{
// enumの定義をフラグ化およびスキャンするユーティリティ
template <typename E, E Last, int FirstEnum = 0> // ,...
struct EnumList {
using value_type = typename std::underlying_type<...
static const int First = FirstEnum;
static const int Count = static_cast<int>(Last) -...
// Enumをフラグとして扱うクラス。(32個もしくは64個以内)
template <typename IntT>
struct FlagsT {
IntT flags_ = 0;
FlagsT() : flags_(0) {}
FlagsT(IntT flags) : flags_(flags) {}
FlagsT(E value) { set(value); }
// 初期化(すべてオフ)
void clear() { flags_ = 0; }
// フラグセット
void set(E value) {
flags_ |= static_cast<IntT>(1) << static_...
}
void reset(E value) {
flags_ &= ~(static_cast<IntT>(1) << static_cast<int>(...
}
// セットされているフラグの数を返す
uint32_t count() const {
uint32_t count = 0;
for (value_type n = First; n < static_cas...
if ((flags_ & (1 << n)) != 0) ++count;
}
return count;
}
// check
bool operator() (E value) const {
return (flags_ & (static_cast<IntT>(1) <<...
}
// フラグの連結
FlagsT& operator | (E value) {
set(value);
return *this;
}
// フラグがOnのenumをなめる
template <typename Proc>
void eachEnum(Proc proc) const {
for (value_type n = First; n < static_cas...
if ((flags_ & (1 << n)) != 0) {
proc(static_cast<E>(n));
}
}
}
};
using Flags = FlagsT<uint32_t>;
using Flags64 = FlagsT<uint64_t>;
// enumを[First,Last)でなめる
template <typename Proc>
static void eachEnum(Proc proc) {
for (value_type n = First; n < static_cast<va...
proc(static_cast<E>(n));
}
}
}}
* Chapter-3 enumをboost::adaptorsから使いたい [#w3909b06]
EnumListでenumの操作が楽になりましたが、現実的にはenum変...
クラスオブジェクトのリストを走査する場合に、enum変数を値...
** 3-1 boost adaptorsでenumを便利に使う [#i3ccf435]
名前と国籍から構成されるクラスとそのリストがあります
#sh(cpp){{
struct Human {
string name_; // 名前
Nationality nationality_; // 国籍
};
vector<Human> people; // Humanのリスト
}}
boost::adaptorsを使用しない場合、peopleにある日本国籍のHu...
#sh(cpp){{
for (auto& human : people) {
if (human.nationality_ != Nationality::Japanese) cont...
hoge(human); /// 何らかの処理
};
}}
boost::adaptors::filteredを使うとこうなります
#sh(cpp){{
using boost::adaptors::filtered;
for (auto& human : people | filtered([](auto& human) { re...
hoge(human); /// 何らかの処理
};
}}
filteredを使用するとちょっとカッコイイですね。
でも、冗長さはあまり変わりません。
** 3-2 EnumAdapter [#v0ed8b41]
そこで、boost::adaptoersでenumを扱うためのヘルパークラス ...
こんな具合に書けます
#sh(cpp){{
using boost::adaptors::filtered;
for (auto& human : people | filtered(+Nationality::Japane...
hoge(human); /// 何らかの処理
};
}}
スッキリしましたね。 Nationality列挙体の単項演算子'+'がミ...
もうおわかりだと思いますが、こんな風にも書けます。
#sh(cpp){{
// 特定条件での走査 (日本人とフランス人を対象とする)
for (auto& h : people | filtered(Nationality::Japanese | ...
hoge(human); /// 何らかの処理
}
}}
サッパリしてますね。以下の従来の書き方と比べてみてください
#sh(cpp){{
// 特定条件での走査 (日本人とフランス人を対象とする)
for (auto& h : people | filtered([](auto& h) {
return h.nationality_ == Nationality::Japanese || h.nati...
hoge(human); /// 何らかの処理
}
}}
よく見ると、filterd(+Nationality::Japanese) が、Human構...
もちろん、これには種も仕掛けもございます。
** 3-3 構造体のメンバ変数を型から取得するためのgetter定義...
種明かしをすると、以下の一行が追加されています
#sh(cpp){{
struct Human {
string name_; // 名前
Nationality nationality_; // 国籍
FSG_MAKE_GETTER(name_, nationality_);
};
}}
''悪魔のマクロ定義ですね''
まだ悪魔に魂を売り渡したくない人は、以下のように記述して...
#sh(cpp){{
struct Human {
string name_; // 名前
Nationality nationality_; // 国籍
template<typename T> const T& get() const {
return *boost::fusion::find<const T&>(boost::fusi...
}
};
}}
このgetterは、get<型>() からクラス構造体のメンバ変数にア...
** 3-4 EnumAdapterの実装 [#m3f00e59]
EnumAdapterの実装です
#sh(cpp){{
// Enumlateをorで結合し、条件判定を行うためのアダプタク...
template <typename E, typename Pred, typename FlagT = ui...
struct EnumPredAdapter {
using value_type = FlagT;
value_type flags_ = 0;
// constructor
EnumPredAdapter(value_type v) : flags_(v) {}
EnumPredAdapter(E a) : flags_(toFlag(a)) {}
EnumPredAdapter(E a, E b) : flags_(toFlag(a) | toFlag(b...
// enum値からフラグにする
static value_type toFlag(E value) { return 1 << static_...
// operator
EnumPredAdapter operator | (E a) { return flags_ | toFl...
EnumPredAdapter operator | (EnumPredAdapter a) { return...
EnumPredAdapter operator & (EnumPredAdapter a) { return...
template<typename T>
bool operator == (const T& src) const { return this->op...
template<typename T>
bool operator () (const T& src) const {
return Pred::comp(toFlag(src.template get<E>()), flags...
}
};
struct EnumPredAny { template<typename VT> static bool c...
struct EnumPredNot { template<typename VT> static bool c...
template <typename T, typename E, typename Pred, typenam...
inline bool operator == (const T& src, EnumPredAdapter<E...
template <typename T, typename E, typename Pred, typenam...
inline bool operator != (const T& src, EnumPredAdapter<E...
}
// 引数で指定したT型の変数をget<T>()で取得するためのマクロ
// eg.
// struct { int a; float b, string c; FSG_MAKE_GETTER(a,b...
// get<int>()でa、get<float>()でb、get<string>()でcが取得...
#define FSG_MAKE_GETTER(...) \
template<typename T> const T& get() const {\
return *boost::fusion::find<const T&>(boost::fusion::...
}}
* おわりに [#end]
長い文章を最後まで読んでいただいてありがとうございました。
簡単なクラスですが、enum変数の操作をスッキリかけるように...
今回も、boost::fusionの使い方について、高橋晶さんに助けて...
fusionもとても便利なクラスなので、機会があればどんどん使...
終了行:
&size(30){&color(darkblue,#c0c0ff){''C++(14) Enumerateユ...
#counter
*はじめに [#x761471e]
[[C++AdventCalender2015>http://www.adventar.org/calendars...
21日目の記事は、Yuki Maria Miyatakeさんによる[[boost.Asio...
23日目の記事は、on_origami さんによる[[MATLABとC++の奇妙...
Advent Calendarに参加するのも今年で4年目になりました。~
ゲームプログラミングにC++11を導入して約2年半あまり。最近...
痒いところに手がとどくようになってきたC++14ですが、便利に...
そこで、以前から自前で作成していたenumerateツールをC++14...
12/25加筆~
プログラムにミスがありました。VisualStudio以外でエラーに...
3-4 EnumAdapterの実装の22行目~
#sh(cpp){{
- return Pred::comp(toFlag(src.get<E>()), flags_);
+ return Pred::comp(toFlag(src.template get<E>()), flag...
}}
-----
* もくじ [#md950fd7]
- [[Chapter-1 enumの走査を便利にする>#w3909b06]]
--[[1-1 enumrateの走査>#f1d8f37b]]
--[[1-2 EnumListの定義>#f1d8f37b]]
- [[Chapter-2 enumをフラグとして使いたい>#w3909b06]]
--[[2-1 従来の方法の問題点>#f1d8f37b]]
--[[2-2 EnumListを利用したenumerateのフラグ化>#ve9131f4]]
--[[2-3 EnumList::Flagsの実装>#ve9131f4]]
- [[Chapter-3 enumをboost::adaptorsから使いたい>#w3909b06]]
--[[3-1 boost adaptorsでenumを便利に使う>#i3ccf435]]
--[[3-3 構造体のメンバ変数を型から取得するためのgetter定...
--[[3-4 EnumAdapterの実装>#m3f00e59]]
- [[おわりに>#end]]
-----
* Chapter-1 enumの走査を便利にする[#w3909b06]
** 1-1 enumrateの走査 [#f1d8f37b]
国籍を表すenumerate定義
#sh(cpp){{
enum class Nationality {
Japanese, // 日本
American, // アメリカ
German, // ドイツ
French, // フランス
Russian, // ロシア
};
}}
すべてのNationalityを走査するには?
#sh(cpp){{
for (int n = 0; n <= static_cast<int>(Nationality:: Russi...
auto nationality = static_cast<Nationality>(n);
hoge(nationality); // Natioanlityを使用した処理
}
}}
static_castが''冗長でイヤ''ですね
こんな風に書けたら便利です~
#sh(cpp){{
NationalityList::eachEnum([](auto nationality) {
hoge(nationality); // Natioanlityを使用した処理
});
}}
EnumListというヘルパークラスを作りました
#sh(cpp){{
using NationalityList = EnumList<Nationality, Nationality...
}}
これでOK~
終端を定義するために、列挙体の最後に'End'を追加してありま...
#sh(cpp){{
enum class Nationality {
Japanese, // 日本
American, // アメリカ
German, // ドイツ
French, // フランス
Russian, // ロシア
End, // end of Nationality
};
}}
利用制限として、値が1ずつ増えることと、既存の定義に含まれ...
** 1-2 EnumListの定義 [#f1d8f37b]
#sh(cpp){{
// enumの定義をフラグ化およびスキャンするユーティリティ
template <typename E, E Last, int FirstEnum = 0>
struct EnumList {
using value_type = typename std::underlying_type<...
static const int First = FirstEnum;
static const int Count = static_cast<int>(Last) -...
// enumを[First,Last)でなめる
template <typename Proc>
static void eachEnum(Proc proc) {
for (value_type n = First; n < static_cast<va...
proc(static_cast<E>(n));
}
}
}}
これで、EnumList<First,Last>::eachEnum(Proc)という書式で...
* Chapter-2 enumをフラグとして使いたい [#w3909b06]
** 2-1 従来の方法の問題点 [#f1d8f37b]
フラグの定義はいにしえのCの時代から大きく変化していません...
#defineをenumもしくはconst intに置き換えた程度で、使い勝...
国情報のフラグ化の例
#sh(cpp){{
enum class NationalityBitFlags {
Japanese = 1 << 0, // 日本
American = 1 << 1, // アメリカ
German = 1 << 2, // ドイツ
French = 1 << 3, // フランス
Russian = 1 << 4, // ロシア
};
}}
国籍のフラグに日本が含まれているか否かをチェックする関数...
#sh(cpp){{
bool isJapanese(NationalityBitFlags n) {
return (static_cast<int>(n) & static_cast<int>(Nationali...
}
}}
''static_castが冗長でイヤですね''
さらに条件が少し複雑(ヨーロッパ限定)になると、
#sh(cpp){{
bool isEuropean(Nationality n) {
return (static_cast<int>(n) & (
static_cast<int>(Nationality::German)|
static_cast<int>(Nationality::French)|
static_cast<int>(Nationality::Russian)) != 0;
}
}}
''とてもイヤな感じですね''
いまどきのC++でこんなコードは書きたくないです!~
**2-2 EnumListを利用したenumerateのフラグ化 [#ve9131f4]
先ほどのEnumListクラスにフラグを扱うクラスを追加して、以...
#sh(cpp){{
using NationalityFlags = EnumList<Nationality, Nationalit...
// 日本人か?
bool isJapanese(Nationality n) {
return NationalityFlags(n)(Nationality::Japanese);
}
// ヨーロッパ人か?
bool isEuropean(Nationality n) {
return NationalityFlags(n)(Nationality::German | Nationa...
}
}}
スッキリしました。enumの値を|で結合して簡単に比較ができま...
フラグがセットされているものだけ走査することもできます
#sh(cpp){{
NationalityFlags euro(Nationality::German | Nationality::...
euro.eachEnum([](auto nationality) {
hoge(nationality); // ドイツ、フランス、ロシアが実行...
});
}}
**2-3 EnumList::Flagsの実装 [#ve9131f4]
EnumListにFlagsというクラスを追加しました
#sh(cpp){{
// enumの定義をフラグ化およびスキャンするユーティリティ
template <typename E, E Last, int FirstEnum = 0> // ,...
struct EnumList {
using value_type = typename std::underlying_type<...
static const int First = FirstEnum;
static const int Count = static_cast<int>(Last) -...
// Enumをフラグとして扱うクラス。(32個もしくは64個以内)
template <typename IntT>
struct FlagsT {
IntT flags_ = 0;
FlagsT() : flags_(0) {}
FlagsT(IntT flags) : flags_(flags) {}
FlagsT(E value) { set(value); }
// 初期化(すべてオフ)
void clear() { flags_ = 0; }
// フラグセット
void set(E value) {
flags_ |= static_cast<IntT>(1) << static_...
}
void reset(E value) {
flags_ &= ~(static_cast<IntT>(1) << static_cast<int>(...
}
// セットされているフラグの数を返す
uint32_t count() const {
uint32_t count = 0;
for (value_type n = First; n < static_cas...
if ((flags_ & (1 << n)) != 0) ++count;
}
return count;
}
// check
bool operator() (E value) const {
return (flags_ & (static_cast<IntT>(1) <<...
}
// フラグの連結
FlagsT& operator | (E value) {
set(value);
return *this;
}
// フラグがOnのenumをなめる
template <typename Proc>
void eachEnum(Proc proc) const {
for (value_type n = First; n < static_cas...
if ((flags_ & (1 << n)) != 0) {
proc(static_cast<E>(n));
}
}
}
};
using Flags = FlagsT<uint32_t>;
using Flags64 = FlagsT<uint64_t>;
// enumを[First,Last)でなめる
template <typename Proc>
static void eachEnum(Proc proc) {
for (value_type n = First; n < static_cast<va...
proc(static_cast<E>(n));
}
}
}}
* Chapter-3 enumをboost::adaptorsから使いたい [#w3909b06]
EnumListでenumの操作が楽になりましたが、現実的にはenum変...
クラスオブジェクトのリストを走査する場合に、enum変数を値...
** 3-1 boost adaptorsでenumを便利に使う [#i3ccf435]
名前と国籍から構成されるクラスとそのリストがあります
#sh(cpp){{
struct Human {
string name_; // 名前
Nationality nationality_; // 国籍
};
vector<Human> people; // Humanのリスト
}}
boost::adaptorsを使用しない場合、peopleにある日本国籍のHu...
#sh(cpp){{
for (auto& human : people) {
if (human.nationality_ != Nationality::Japanese) cont...
hoge(human); /// 何らかの処理
};
}}
boost::adaptors::filteredを使うとこうなります
#sh(cpp){{
using boost::adaptors::filtered;
for (auto& human : people | filtered([](auto& human) { re...
hoge(human); /// 何らかの処理
};
}}
filteredを使用するとちょっとカッコイイですね。
でも、冗長さはあまり変わりません。
** 3-2 EnumAdapter [#v0ed8b41]
そこで、boost::adaptoersでenumを扱うためのヘルパークラス ...
こんな具合に書けます
#sh(cpp){{
using boost::adaptors::filtered;
for (auto& human : people | filtered(+Nationality::Japane...
hoge(human); /// 何らかの処理
};
}}
スッキリしましたね。 Nationality列挙体の単項演算子'+'がミ...
もうおわかりだと思いますが、こんな風にも書けます。
#sh(cpp){{
// 特定条件での走査 (日本人とフランス人を対象とする)
for (auto& h : people | filtered(Nationality::Japanese | ...
hoge(human); /// 何らかの処理
}
}}
サッパリしてますね。以下の従来の書き方と比べてみてください
#sh(cpp){{
// 特定条件での走査 (日本人とフランス人を対象とする)
for (auto& h : people | filtered([](auto& h) {
return h.nationality_ == Nationality::Japanese || h.nati...
hoge(human); /// 何らかの処理
}
}}
よく見ると、filterd(+Nationality::Japanese) が、Human構...
もちろん、これには種も仕掛けもございます。
** 3-3 構造体のメンバ変数を型から取得するためのgetter定義...
種明かしをすると、以下の一行が追加されています
#sh(cpp){{
struct Human {
string name_; // 名前
Nationality nationality_; // 国籍
FSG_MAKE_GETTER(name_, nationality_);
};
}}
''悪魔のマクロ定義ですね''
まだ悪魔に魂を売り渡したくない人は、以下のように記述して...
#sh(cpp){{
struct Human {
string name_; // 名前
Nationality nationality_; // 国籍
template<typename T> const T& get() const {
return *boost::fusion::find<const T&>(boost::fusi...
}
};
}}
このgetterは、get<型>() からクラス構造体のメンバ変数にア...
** 3-4 EnumAdapterの実装 [#m3f00e59]
EnumAdapterの実装です
#sh(cpp){{
// Enumlateをorで結合し、条件判定を行うためのアダプタク...
template <typename E, typename Pred, typename FlagT = ui...
struct EnumPredAdapter {
using value_type = FlagT;
value_type flags_ = 0;
// constructor
EnumPredAdapter(value_type v) : flags_(v) {}
EnumPredAdapter(E a) : flags_(toFlag(a)) {}
EnumPredAdapter(E a, E b) : flags_(toFlag(a) | toFlag(b...
// enum値からフラグにする
static value_type toFlag(E value) { return 1 << static_...
// operator
EnumPredAdapter operator | (E a) { return flags_ | toFl...
EnumPredAdapter operator | (EnumPredAdapter a) { return...
EnumPredAdapter operator & (EnumPredAdapter a) { return...
template<typename T>
bool operator == (const T& src) const { return this->op...
template<typename T>
bool operator () (const T& src) const {
return Pred::comp(toFlag(src.template get<E>()), flags...
}
};
struct EnumPredAny { template<typename VT> static bool c...
struct EnumPredNot { template<typename VT> static bool c...
template <typename T, typename E, typename Pred, typenam...
inline bool operator == (const T& src, EnumPredAdapter<E...
template <typename T, typename E, typename Pred, typenam...
inline bool operator != (const T& src, EnumPredAdapter<E...
}
// 引数で指定したT型の変数をget<T>()で取得するためのマクロ
// eg.
// struct { int a; float b, string c; FSG_MAKE_GETTER(a,b...
// get<int>()でa、get<float>()でb、get<string>()でcが取得...
#define FSG_MAKE_GETTER(...) \
template<typename T> const T& get() const {\
return *boost::fusion::find<const T&>(boost::fusion::...
}}
* おわりに [#end]
長い文章を最後まで読んでいただいてありがとうございました。
簡単なクラスですが、enum変数の操作をスッキリかけるように...
今回も、boost::fusionの使い方について、高橋晶さんに助けて...
fusionもとても便利なクラスなので、機会があればどんどん使...
ページ名: