Сравнение перечисления из шаблонного класса - это безопасно? - PullRequest
4 голосов
/ 21 января 2011

Итак, простой вопрос на самом деле, проиллюстрированный на примере ниже. Когда вы компилируете это, компилятор соответствующим образом (?) Выдает предупреждение (что мы сравниваем barfoo<int>::bar с barfoo<foo>::bar), теперь, учитывая, что bar является перечислением - могу ли я безопасно проигнорировать это предупреждение?

#include <iostream>

using namespace std;
struct foo
{
};

template <typename bob = int>
struct barfoo
{
  enum bar { ONE, TWO, THREE };

  bar action() const { return TWO; }
};

template <barfoo<>::bar eAction = barfoo<>::ONE>
struct IsAction
{
  template <typename bf>
  static bool check(bf const& cState)
  {
    return cState.action() == eAction;
  }  
};

int main(void)
{
  barfoo<foo> c;

  cout << IsAction<>::check(c) << endl;

  return 0;
}

Учитывая, что я сторонник удаления предупреждающих сообщений, есть ли способ удовлетворить компилятор , не перемещая перечисление за пределы ?

Ответы [ 3 ]

3 голосов
/ 21 января 2011

Числовое представление перечислений будет одинаковым, поэтому можно сравнивать их напрямую (или даже приводить между ними, хотя вам может потребоваться выполнить int, чтобы удовлетворить компилятор). Если вы хотите заставить замолчать предупреждение, одним из подходов будет приведение их обоих к целым числам перед выполнением сравнения: (int)cState.action == (int)eAction. Возможно, вы сможете добавить шаблон operator==, чтобы перечисление делало это автоматически - хотя в этом нет уверенности.

С другой стороны, в зависимости от того, как вы определяете «не перемещая перечисление за пределы», вы можете получить производный от не-шаблонного базового класса, который служит для хранения определения перечисления, как в http://codepad.org/8bVlcas3

1 голос
/ 21 января 2011

Я бы переместил его наружу, но в базовый класс:

struct barenum
{ 
   enum bar { ONE, TWO, THREE };

 protected: // because we are going to derive from it without a virtual destructor
   ~barenum() {}
};

template <typename bob = int>
struct barfoo : barenum
{
  bar action() const { return TWO; }
};
0 голосов
/ 21 января 2011

Перемещает ли enum в родительский элемент счетчика barfoo?

#include <iostream>

using namespace std;
struct foo
{
};

struct barfoobase
{
  enum bar { ONE, TWO, THREE };
};

template <typename bob = int>
struct barfoo : public barfoobase
{
  bar action() const { return TWO; }
};

template <barfoobase::bar eAction = barfoobase::ONE>
struct IsAction
{
  template <typename bf>
  static bool check(bf const& cState)
  {
    return cState.action() == eAction;
  }  
};

int main(void)
{
  barfoo<foo> c;

  cout << IsAction<>::check(c) << endl;

  return 0;
}

edit: Упс, этот ответ уже опубликован ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...