ニールが言ったように、私は自分で問題に直面したことはありません。ただし、コードセットの問題に直面しました(つまり、文字列から列挙型へのマッピング、およびその逆)。
私の最初の反応は表皮性です:DRY.
ご指摘のとおり、2 つの列挙型と翻訳を維持するには時間がかかるため、リファクタリングして 1 つだけを使用することをお勧めします。
私の2番目の反応は、列挙型を削除しようとすることです。私は列挙型が好きではありません。おそらく、来たる C++0x でそれらに感謝することになるでしょうが、現状では、私の考えでは価値がある以上に厄介なものです。カテゴリなどを備えたスマートオブジェクトが好きです...
でも、問題自体は面白いと思います。この厄介な状況に対処したいのであれば、私はあなたの負担を軽減するように努めたほうがよいでしょう。
ここでは、テンプレートはあまり機能しません。列挙型の範囲チェック、文字列変換 (前後) および反復に使用しましたが、できることはそれだけです。ただし、ご想像のとおり、Boost.Preprocessor の「微妙な」アプリケーションで可能です。
書きたいこと:
DEFINE_CORRESPONDING_ENUMS(Server, Client,
((Server1, 1, Client1, 6))
((Server2, 2, Client2, 3))
((Common1, 4, Common1, 4))
((Common2, 5, Common2, 5))
((Server3, 7, Client3, 1))
);
そして、それを生成したいと思います:
struct Server
{
enum type { Server1 = 1, Server2 = 2, Common1 = 4, Common2 = 5, Server3 = 7 };
};
struct Client
{
enum type { Client1 = 6, Client2 = 3, Common1 = 4, Common2 = 5, Client3 = 1 };
};
Server::type ServerFromClient(Client::type c)
{
switch(c)
{
case Client1: return Server1;
//...
default: abort();
}
}
Client::type ClientFromServer(Server::type s)
{
//...
}
良いニュースは、これは可能です。私はそれを行うことさえできますが、おそらくあなたに少し作業を任せます;)
ここにいくつかの説明があります:
- マクロの 3 番目の要素はシーケンスです。シーケンスのサイズは無制限です。
- シーケンスの各要素は 4 タプルです。そのサイズを事前に知る必要があるため、 の繰り返しです
Common
。代わりにシーケンスを使用した場合、可変数の要素を処理できます (たとえば、共通の繰り返しを避けるため...)。ただし、物事ははるかに複雑になります。
- を参照する必要があります
BOOST_PP_SEQ_FOREACH
。ここでの基本的な操作になります。
BOOST_PP_CAT
トークンの連結を処理することを忘れないでください。
gcc
オプションでは-E
、プリプロセッサの出力が生成されます。便利な場合があります...
- コメントとファイルでの使用方法を忘れないでください。そうしないと、同僚に嫌われます