2017-02-17 4 views
2

Я пишу небольшую обертку вокруг OpenGL, чтобы использовать ее объектно-ориентированным способом. Я создал класс, называемый буфером, и в его конструкторе я хотел бы, чтобы он проверял тип буфера, который был передан против множества типов GLenum. Вот соответствующая часть кода:code style - Как я могу проверить целое число против множества возможных значений?

В этом коде switch заявление вмешается к соответствующему значению, и пройти через другие допустимые значения, пока не вырвались из switch заявления. Все остальные значения будут входить в предложение default и выдавать исключение. Я мог бы, однако, также использовать if заявление:

if (type != GL_ARRAY_BUFFER && 
    type != GL_ATOMIC_COUNTER_BUFFER && 
    type != GL_COPY_READ_BUFFER && 
    type != GL_COPY_WRITE_BUFFER && 
    // *** Lots more valid values here... *** 
    ) { 
     throw std::logic_error("Invalid GLenum 'type' in Buffer constructor."); 
    } 

    // ... 
} 

Однако, это использует много повторения type != и не обязательно яснее. Есть ли принятое соглашение при этом, для ясность кода и для скорость? Должен ли я вообще проверять мои входы, когда это не может привести к неопределенному поведению?

+0

Первый вопрос: может ли функция, созданная значением 'type', действительно возвращать недопустимое значение? –

+0

@NeilButterworth Значение 'type', как правило, жестко закодировано и не зависит от функции, но мои одноклассники будут использовать этот« класс », и я не могу полагаться на них, чтобы следовать моей документации. –

+1

http://stackoverflow.com/questions/97987/advantage-of-switch-over-if-else-statement Коммутатор с большей вероятностью генерирует эффективный код даже с 20-летним компилятором. – Olivier

ответ

4

Я хотел бы использовать std::set, если есть много значений:

static std::set<int> invalidValues = 
    { GL_ARRAY_BUFFER 
    , GL_ATOMIC_COUNTER_BUFFER 
    , GL_COPY_READ_BUFFER 
    , GL_COPY_WRITE_BUFFER   
    // ... 
    }; 

if(invalidValues.find(type) != invalidValues.end()) { 
    throw std::logic_error("Invalid GLenum 'type' in Buffer constructor."); 
} 

Это будет служить для скорости и лучшей читаемости.

Следует ли вообще проверять мои входы, если это не может привести к неопределенному поведению?

Вы никогда не хотите undefined поведение в вашей программе. Вы не можете полагаться, что это приведет к исключению (сбою) или такому.

+0

Это именно то, что я искал. Благодаря! –

+1

Если значения в наборе не нужно сортировать, используйте 'std :: unordered_set', и если вам действительно не нужно использовать результат' std :: find', подумайте об использовании 'std :: any_of' или 'std :: none_of' – YoungJohn

+1

@YoungJohn В этом случае это выглядит так:' std :: unordered_set' и 'std :: none_of' являются более подходящими. –

Смежные вопросы