2

編集:

があれば簡単ですが、この特定enumの場合には を使用できません。enum実際には、さらに処理するために文字列が必要です。


たとえば、次の 4 つの状態文字列があります。

IDLE, STARTED, STOPPED, PAUSED

そして、これらの状態の 1 つを吸収する関数:

setState(const std::string &state);

if次のような巨大なステートメントを使用せずに、入力状態が 4 つの文字列のいずれかであることを確認する簡単な方法はありますか。

if (state == "IDLE" || state == "STARTED" || state == "STOPPED" || state == "PAUSED") { 
// use code
}
4

5 に答える 5

9

最良の方法は、常に列挙型を使用することです。ただし、std::string に固執する必要がある場合は、次のようなものをお勧めします。

#include <unordered_set>

static void setState(const std::string &state)
{
    static std::unordered_set<std::string> states {{ "IDLE", "STARTED", "STOPPED", "PAUSED" }};
    if (states.find(state) == states.end())
        throw std::invalid_argument("Invalid state");

    // Continue...
}
于 2013-09-13T18:42:29.767 に答える
3

試す:

std::string tmp[] = {"IDLE", "STARTED", "STOPPED", "PAUSED"};
std::set<std::string> allowedStates(tmp, tmp + sizeof(tmp) / sizeof(tmp[0]));

(おそらく静的変数か何かで)

その後:

if (allowedStates.find(state) == allowedStates.end())
{
  //state is invalid
}
于 2013-09-13T18:42:51.877 に答える
1

それは、「迅速な方法」が何を意味するかによって異なります。これが効率に関するものである場合は、最初にサイズをオンにします。

bool verify_state( const std::string& state ) {
  switch( state.size() )
  {
  case 4: return state=="IDLE";
  case 6: return state=="PAUSED";
  case 7: return state=="STARTED" || state == "STOPPED";
  default: return false;
  }
}
于 2013-09-13T18:40:23.167 に答える
1

STL セットを使用した BartoszKP のソリューションは、おそらく最もシンプルなソリューションです。

あなたが本当に熱心なら、次のようなもので貧乏人のハッシュをシミュレートできます:

const unsigned nIdle('ELDI');    // "IDLE" with byte order reversed
const unsigned nStarted('RATS'); // "STAR" with byte order reversed
const unsigned nStopped('POTS'); // "STOP" with byte order reversed
const unsigned nPaused('SUAP');  // "PAUS" with byte order reversed

bool Verify(const char *szState)
{
    unsigned nState = *reinterpret_cast<const unsigned *>(szState);

    switch (nState)
    {
        case nIdle:
        case nStarted:
        case nStopped:
        case nPaused:
            return true;

        default:
            return false;
    }
}

int main()
{
    const std::string s[] = {"IDLE", "STARTED", "STOPPED", "PAUSED", "INVALID"};
    for (auto itr=std::begin(s); itr!=std::end(s); ++itr)
    {
        std::cout << *itr << '\t';
        if (Verify(itr->c_str()))
            std::cout << "OK";
        else
            std::cout << "Fail";
        std::cout << std::endl;
    }
    return 0;
}

データを確認する必要があります。sizeof(unsigned) より短い文字列は危険である可能性があり、文字列が最初の 4 バイトで一意であることを確認する必要があります。たとえば、"STOPPED" と "STOPPING" は 4 バイトで同じです。

適切なハッシュを行うこともできますが、文字列を比較するよりも高速ではない可能性があります。

于 2013-09-13T19:43:10.617 に答える