3

1つのホストが1バイトのコマンドを受信できるプロトコルを実装しています。

バイトには256の可能な値がありますが、有効な値はごくわずかです。

もちろん、私は次のようなものを書くことができます:

bool is_valid(uint8_t command)
{
  switch (command)
  {
    case 0x00:
    case 0x01:
    case 0xa0:
    case 0xa1:
      return true;
  }

  return false;
}

受信したコマンドの有効性を実行時に確認します。

残念ながら、これらのコマンドのすべての名前のリストも維持する必要があります。これにより、非常に近い別の関数を作成する必要is_valid()がありますが、代わりにコマンドの名前が返されます。そうすることで、有効なコマンドのリストを複製することになりますが、私はそれが好きではありません。

メタプログラミングを使って有効なコマンドを一度だけ宣言する方法があるのではないかと思いました。

何かのようなもの:

template <uint8_t Value>
struct valid_value_type;

struct valid_value_type<0x00> { static const std::string name = "Stop command"; };
struct valid_value_type<0x01> { static const std::string name = "Start command"; };

is_valid()しかし、満足のいくもの(「コンパイルと動作」を理解)に到達できず、これらのテンプレート宣言の存在を自動的に考慮する適応関数を生成する方法がわかりません。

それも可能ですか?もしそうなら、あなたはそれをどのように行いますか?

注:残念ながらC ++ 11はオプションではありませんが、好奇心からこのソリューションにも興味があります。

4

2 に答える 2

2

組み込み環境でない限り、 a には 256 個の可能な値しかuint8_tないため、それを使用してルックアップ テーブルを作成するのは恐ろしいことではありません...

char const * cmds[256] = {};
void cmds_init(char const * (&cmds)[256]) {
   cmds[0x00] = "Stop command";
// ...
}

次に、有効なコマンドのテストは、ルックアップ テーブルで名前を見つけることです。

bool is_valid(uint8_t cmd) {
   return cmds[cmd] != 0;
}

有効なコマンドの数が 256 よりもはるかに少ない場合は、スイッチを使用して名前を返すか、コマンドが不明な場合は null を返す関数を実装して、同じアプローチを使用できます。

于 2013-03-04T20:33:01.553 に答える
1

以下の行に沿って何かしますか?

template <uint8_t Value>
struct valid_value_type
{
  static char const *const name = 0;
};

template<>
struct valid_value_type<0x00>
{
  static char const *const name = "Stop command";
};

template<>
struct valid_value_type<0x01>
{
  static char const *const name = "Start command";
};

template <uint8_t N>
bool is_valid_value_type_helper(uint8_t value, valid_value_type<N>)
{
  return((value == N) ? valid_value_type<N>::name != 0 : check_valid_value_type_helper(value, valid_value_type<N-1>()));
}

bool is_valid_value_type_helper(uint8_t value, valid_value_type<0>)
{
  return(value == 0 && valid_value_type<0>name != 0);
}

bool is_is_valid_value_type(uint8_t value)
{
  return(is_valid_value_type_helper(value, valid_value_type<0xff>());
}

もう少し単純化できそうです…

于 2013-03-04T22:03:14.197 に答える