Почему оператор переключения не может быть применен на строки?

Добавить state:string в пост модель

rails g migration add_state_to_posts state

Или

class Post < ActiveRecord::Base
  include ClassyEnum::ActiveRecord

  classy_enum_attr :state

end

Ссылка => https://github.com/beerlington / classy_enum # 3-установка-The-активная запись-модель

208
задан TangKe 5 September 2018 в 07:03
поделиться

9 ответов

Причина, почему имеет отношение к системе типов. C/C++ действительно не поддерживает строки как тип. Это действительно поддерживает идею постоянного массива символов, но это не действительно полностью понимает понятия строки.

, Чтобы сгенерировать код для оператора переключения, компилятор должен понять то, что это означает, чтобы два значения были равны. Для объектов как ints и перечисления, это - тривиальное разрядное сравнение. Но как компилятор должен сравнить 2 строковых значения? Чувствительный к регистру, нечувствительный, знающая культура, и т.д. Без полной осведомленности о строке этому нельзя точно ответить.

Кроме того, операторы переключения C/C++ обычно сгенерированы как таблицы переходов . Это совсем не как легкое генерировать таблицу переходов для строкового переключателя стиля.

175
ответ дан JaredPar 23 November 2019 в 04:41
поделиться

Вы не можете использовать строку в случае переключателя. Только интервал & символ позволяется. Вместо этого можно попробовать перечисление за представление строки и использовать его в блоке случая переключателя как

enum MyString(raj,taj,aaj);

Использование он интервал оператор выбора переключателя.

0
ответ дан strager 23 November 2019 в 04:41
поделиться

В C++ строки не являются гражданами первого класса. Строковые операции сделаны через стандартную библиотеку. Я думаю, это - причина. Кроме того, C++ использует оптимизацию таблицы переходов для оптимизации операторов case оператора switch. Взгляните на ссылку.

http://en.wikipedia.org/wiki/Switch_statement

3
ответ дан chappar 23 November 2019 в 04:41
поделиться

В C++ можно только использовать оператор переключения на интервале и символе

3
ответ дан CodeMonkey1313 23 November 2019 в 04:41
поделиться

В C++ и C переключает только работу над целыми типами. Еще используйте если лестничная структура вместо этого. C++, возможно, очевидно, реализовал своего рода оператор переключателя для строк - я предполагаю, что никто не думал это стоящий, и я соглашаюсь с ними.

6
ответ дан 23 November 2019 в 04:41
поделиться

Проблема состоит в том, что по причинам оптимизации оператор переключения в C++ ни над чем не работает кроме типов примитивов, и можно только сравнить их с константами времени компиляции.

, По-видимому, причина ограничения состоит в том, что компилятор в состоянии применить некоторую форму оптимизации, компилирующей код вниз в одну cmp инструкцию и goto, где адрес вычисляется на основе значения аргумента во времени выполнения. Начиная с ветвления и и циклы не играют приятно с современными центральными процессорами, это может быть важной оптимизацией.

Для обхождения этого я боюсь, что необходимо будет обратиться к если операторы.

11
ответ дан tomjen 23 November 2019 в 04:41
поделиться

Можно только использовать, включают примитивный, такие как интервал, символ и перечисление. Самое легкое решение сделать это как Вы хочет, должен использовать перечисление.

#include <map>
#include <string>
#include <iostream.h>

// Value-Defintions of the different String values
static enum StringValue { evNotDefined,
                          evStringValue1,
                          evStringValue2,
                          evStringValue3,
                          evEnd };

// Map to associate the strings with the enum values
static std::map<std::string, StringValue> s_mapStringValues;

// User input
static char szInput[_MAX_PATH];

// Intialization
static void Initialize();

int main(int argc, char* argv[])
{
  // Init the string map
  Initialize();

  // Loop until the user stops the program
  while(1)
  {
    // Get the user's input
    cout << "Please enter a string (end to terminate): ";
    cout.flush();
    cin.getline(szInput, _MAX_PATH);
    // Switch on the value
    switch(s_mapStringValues[szInput])
    {
      case evStringValue1:
        cout << "Detected the first valid string." << endl;
        break;
      case evStringValue2:
        cout << "Detected the second valid string." << endl;
        break;
      case evStringValue3:
        cout << "Detected the third valid string." << endl;
        break;
      case evEnd:
        cout << "Detected program end command. "
             << "Programm will be stopped." << endl;
        return(0);
      default:
        cout << "'" << szInput
             << "' is an invalid string. s_mapStringValues now contains "
             << s_mapStringValues.size()
             << " entries." << endl;
        break;
    }
  }

  return 0;
}

void Initialize()
{
  s_mapStringValues["First Value"] = evStringValue1;
  s_mapStringValues["Second Value"] = evStringValue2;
  s_mapStringValues["Third Value"] = evStringValue3;
  s_mapStringValues["end"] = evEnd;

  cout << "s_mapStringValues contains "
       << s_mapStringValues.size()
       << " entries." << endl;
}

Код, записанный Stefan Ruck 25-го июля 2001.

31
ответ дан Matthew D. Scholefield 23 November 2019 в 04:41
поделиться

Как упомянуто ранее, компиляторам нравится создавать таблицы поиска, которые оптимизируют switch операторы к около O (1) синхронизация, когда это возможно. Объедините это с тем, что Язык C++ не имеет строкового типа - std::string, часть Стандартной Библиотеки, которая не является частью Языка по сути.

я предложу альтернативу, которую Вы могли бы хотеть рассмотреть, я использовал ее в прошлом успешно. Вместо того, чтобы переключить саму строку, переключите результат хеш-функции, которая использует строку в качестве входа. Ваш код будет почти так же ясен как переключение строки при использовании предопределенного набора строк:

enum string_code {
    eFred,
    eBarney,
    eWilma,
    eBetty,
    ...
};

string_code hashit (std::string const& inString) {
    if (inString == "Fred") return eFred;
    if (inString == "Barney") return eBarney;
    ...
}

void foo() {
    switch (hashit(stringValue)) {
    case eFred:
        ...
    case eBarney:
        ...
    }
}

существует набор очевидной оптимизации, которая в значительной степени следует за тем, что компилятор C сделал бы с оператором переключения... забавным, как это происходит.

54
ответ дан D.Shawley 23 November 2019 в 04:41
поделиться

Я думаю, что причина состоит в том, которые в струнах до не типы примитивов, как tomjen сказал, думайте в строке как массив символов, таким образом, Вы не можете сделать вещей как:

switch (char[]) { // ...
switch (int[]) { // ...
4
ответ дан grilix 23 November 2019 в 04:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: