7

私はおそらく不可能を達成しようとしていますが、StackExchange にはいつも驚かされるので、ぜひ試してみてください。

名前を整数にマップする必要があります。名前 (約 2k) は一意です。そのリストへの追加や削除はなく、実行時に値が変更されることはありません。

それらを変数として実装すると、const intコンパイル時に存在と型をチェックできます。また、これは非常に明確で冗長なコードです。エラーは簡単に見つかります。

それらを as として実装するstd::map<std::string, int>と、文字列操作で検索する名前を構築するための柔軟性が大幅に向上します。これを使用して、その文字列にプレ/サフィックスを追加することにより、複数の値のリストを照会できる関数に文字列をパラメーターとして渡すことができます。ループ変数からキー名の数字部分を作成することで、複数の値をループすることもできます。

今私の質問は: 両方の利点を組み合わせる方法はありますか? コンパイル時のチェック (特にキーの存在) が欠落しているため、2 番目の方法はほとんど役に立ちません。(特に、バグを見つけるのが難しいキーが存在しない場合はstd::map黙って戻ります0。) しかし、ループ機能とプレ/サフィックス追加機能は非常に便利です。

ブーストなどの追加のライブラリを使用しないソリューションを希望しますが、とにかくそれらを再実装できる可能性があるため、それらを提案してください。

私が地図で何をするかの例:

void init(std::map<std::string, int> &labels)
{        
  labels.insert(std::make_pair("Bob1" , 45 ));
  labels.insert(std::make_pair("Bob2" , 8758 ));
  labels.insert(std::make_pair("Bob3" , 436 ));
  labels.insert(std::make_pair("Alice_first" , 9224 ));
  labels.insert(std::make_pair("Alice_last" , 3510 ));
}

int main() 
{      
  std::map<std::string, int> labels;
  init(labels);

  for (int i=1; i<=3; i++)
  {
    std::stringstream key;
    key << "Bob" << i; 
    doSomething(labels[key.str()]);
  }

  checkName("Alice");
}

void checkName(std::string name)
{
  std::stringstream key1,key2;
  key1 << name << "_first";
  key2 << name << "_last";
  doFirstToLast(labels[key1.str()], labels[key2.str()]);
}

もう 1 つの目標は、ルーチンに示されているコードmain()をできるだけ簡単で冗長なものにすることです。(非プログラマーは理解する必要があります。)init()関数は、いくつかのツールによってコード生成されます。関数は固定されていdoSomething(int)ますが、それらの周りにラッパー関数を書くことができます。のようなヘルパーcheckName() はより複雑になる可能性がありますが、簡単にデバッグできる必要があります。

4

4 に答える 4

1

あなたのすべての要件を理解しているかどうかはわかりませんが、 を使用せずにこのようなものはどうですかstd::map。それぞれ 42、17、37 にマップする "FIRST"、"SECOND"、"THIRD" という 3 つの文字列があるとします。

#include <stdio.h>

const int m_FIRST = 0;
const int m_SECOND = 1;
const int m_THIRD = 2;

const int map[] = {42, 17, 37};

#define LOOKUP(s) (map[m_ ## s])

int main ()
{
  printf("%d\n", LOOKUP(FIRST));
  printf("%d\n", LOOKUP(SECOND));
  return 0;
}

欠点は、可変文字列を で使用できないことですLOOKUP。しかし、値を繰り返し処理できるようになりました。

于 2013-09-01T14:32:16.217 に答える
1

たぶん、このようなもの(テストされていません)?

struct Bob {
    static constexpr int values[3] = { 45, 8758, 436 };
};

struct Alice {
    struct first {
        static const int value = 9224;
    };
    struct last {
        static const int value = 3510;
    };
};

template <typename NAME>
void checkName()
{
    doFirstToLast(NAME::first::value, NAME::last::value);
}

...

constexpr int Bob::values[3]; // need a definition in exactly one TU

int main() 
{
    for (int i=1; i<=3; i++)
    {
       doSomething(Bob::values[i]);
    }

    checkName<Alice>();
}
于 2013-09-01T16:37:05.060 に答える
0

enum を使用すると、コンパイル時のチェックとそれをループすることができます。

列挙型を反復処理するにはどうすればよいですか?

于 2013-09-01T14:40:24.173 に答える