2010-12-09 3 views
7

enum에 지정된 값이 있는지 확인하는 데 사용할 수있는 synatx 이상한 방법이 있습니까?enum 값의 범위를 빠르게 확인하는 방법

예 :

enum fruit_and_vegetables 
{ 
    apples, 
    pears, 
    tomatoes, 
    cucumbers 
} 

int main() 
{ 
    fruit_and_vegetables something = apples; 
    if(something = {apples, pears}) // <-- this here 
     cout << "something is fruit." << endl; 
    else 
     cout "something is a vegetable." << endl; 
    return 0; 
} 

감사합니다!

+2

토마토와 오이가 * 있습니다 * –

+0

은 SCOTUS에 따라하지 ;-p 과일 : http://en.wikipedia.org/wiki/Tomato#Fruit_or_vegetable.3F –

+0

@Noah :'토마토'*이며, '토마토는 *' – ruslik

답변

4

아,이 수행 할 수 있습니다 상당히 쉽게 ...

template <typename T> 
pair<T, fruit_and_vegetables> operator||(T t, fruit_and_vegetables v) { 
    return make_pair(t, v); 
} 

template <typename T> 
bool operator==(fruit_and vegetables lhs, pair<T, fruit_and_vegetables> rhs) { 
    return lhs == rhs.second || lhs == rhs.first; 
} 

는 다음과 같이 사용할 수 있습니다

if (something == (apple || pear || orange)) eat_the_yummy_fruit(something); 
else feed_to_rabbit(something) 

하지만 (apple || (pear || orange)) 할 경우 작동하지 않습니다. 이 문제는 쉽게 해결할 수 있지만 코드를 간단하게 유지하려고했습니다. 나는 이것이 지금까지 큰 열거 형으로 실제로 확장되는 유일한 대답이라고 믿습니다 ...

+0

넓은 범위를 작동시키는 방법이 있습니까? 이것은 순전히 관심 밖일 것입니다, 당신의 솔루션은 내가 원하는 것을 완벽하게 할 수있게 해줍니다! 감사. – rubenvb

4

if (something < tomatoes)...

+1

아, 그렇습니다. "왜 그런 생각을하지 않았습니까?"(C)'...하지만 열거 형 값이 중간 값이고 예제가 더 복잡하거나 정렬되지 않으면 어떻게 될까요? – rubenvb

5

나는 알고있다,하지만 당신이 할 수있는 것은 할당 값을 열거 회원들에게 2^i하지 것이다. 예를 들어 :

enum fruit_and_vegetables 
{ 
    apples = (1<<0), 
    pears  = (1<<1), 
    tomatoes = (1<<2), 
    cucumbers = (1<<3) 
    // ... 
} 

이 그럼 당신은 물론

if (something & (apples | pears | tomatoes)) 
    std::cout << "is tasty" << std::endl; 

로 확인하실 수 있습니다, 이것은 적당한 크기의 열거로 제한됩니다 (I은 최대 32 개 개의 요소를 가질 수 있다고 생각합니다). 당신은 32 개 이상의 (64) 값이있는 경우

편집

, 당신은 이것보다 더 창의적해야합니다.

enum fruit_and_vegetables { 
    apples = 1, //! 
    pears, 
    tomatoes, 
    cucumbers, 
    // ... 
    grapes 
} 
#define FRUIT_AND_VEGETABLES 120 

if ( (1<<something)  & ((1<<apples) | (1<<pears) | (1<<tomatoes)) 
    || (1<<(something-32) & ((1<<(apples-32)) | (1<<(pears-32)) | (1<<(tomatoes-32)))) 
    || ...) { 
    std::cout << "my keyboard is broken, but tastes good" << std::endl; 
} 

을하지만 정말 좋은 해결책이 아니다 : 몇 가지 검사를함으로써, 당신은 여전히 ​​합리적으로 신속하게 할 수 있습니다. 열거 형 수가 많고 여러 클래스로 분할 될 수 있다면 Noah Roberts' answer으로 갈 것입니다. 또 다른 방법이있다

+1

-1은 토마토 맛이 좋다는 이유로! j/k 열거 형에서 이러한 종류의 동작을 원할 때쯤에는 열거 형이 실제로 원하는 동작에 적합한 구조가 아니라고 말할 것입니다. –

+2

농담해야합니다! 토마토는 **** 최고입니다! – bitmask

+2

@bitmask : 열거 형에 70 명의 멤버가 있다면? 이 왼쪽 시프트 접근 방식이 효과가 없을 것입니다! – Nawaz

1

, 즉 @bitmask의 대답을 확장 :

가 확인할 수있는 기준의 고정 된 수의가 가정하자.

enum fruit_and_vegetables { 
    apples = 0, 
    pears, 
    tomatoes, 
    cucumbers 
} 

enum qualifs { 
    is_fruit = 1, 
    is_sweet = 1<<1, 
    is_round = 1<<2, 
    is_tasty = 1<<3 
} 

const qualifs qualifs_LUT[] = { // can be generated 
    is_fruit | is_sweet | is_round, // apple 
    ... 
}; 

때문에 특정 규정의 의지를 확인하는

if (qualifs_LUT[tomato] & is_tasty) 
이 된 것을 : 그래서, 대신 fruit_and_vegetables 열거의 값을 비트 마스크 사용하는, 추가 LUT를 사용할 수 있습니다 (즉, 단어의 크기로 제한됩니다)

편집 : 또 다른 흥미로운 방법입니다. @bitmask : 메소드를 (다시) 고려하십시오. 그것은 2의 거듭 제곱에 의존합니다. 그러나 소수는 어떻습니까? 열거 값에 소수를 할당하여, 더 많은 값을 squize 수 있도록 그들은 해당 제품을 가정, 더 느리게 더 성장하지 않습니다 오버 플로우 :

enum fruit_and_vegetables { 
    apples = 2, 
    pears = 3, 
    tomatoes = 5, 
    cucumbers = 7 
} 

if ((apples * pears * tomatoes) % tomatoes == 0) 
    printf("it's tasty!"); 

이 하나가 제어 세트에있는 항목의 수를 제한한다.

당신은 당신이 원하는 구문 달성하는 데 도움이됩니다 도우미 템플릿을 작성할 수 있습니다
+0

좋아해요! (하지만 너는 아마 lut'const'를 만들어야한다.) – bitmask

+0

@bitmask : 그냥 구현 정보이다. – ruslik

+0

나는 알고있다. 그러나 나는 15 글자를 채워야했다. :) – bitmask

1

:

enum fruit_and_vegetables 
{ 
    nothing, 
    apples, 
    pears, 
    tomatoes, 
    cucumbers 
}; 

// helper template 
typedef fruit_and_vegetables fav; 
template<fav v1 = nothing, fav v2 = nothing, fav v3 = nothing, fav v4 = nothing, 
    fav v5 = nothing, fav v6 = nothing, fav v7 = nothing, fav v8 = nothing> 
bool check_equal(fruit_and_vegetables value) 
{ 
    return (value == v1 || value == v2 || value == v3 || value == v4 || 
      value == v5 || value == v6 || value == v7 || value == v8); 
} 

// usage 
int main() 
{ 
    fruit_and_vegetables something = apples; 
    if(check_equal<apples, pears>(something)) 
     std::cout << "something is fruit." << std::endl; 
    else 
     std::cout << "something is a vegetable." << std::endl; 

    return 0; 
} 
+0

각 값을 수동으로 검사하는 것과 같다. OP는 명백한 것보다 더 빠른 방법을 요구했습니다. – ruslik

+1

OP는 간단한 구문에 대해 물었습니다 : "online way of synatx weirdness". –

1

큰 처리하기 위해 농산물의 분류되지 않은 세트 :

enum fruit_and_vegetables 
{ 
    apples, 
    pears, 
    tomatoes, 
    cucumbers, 
    MAX_VALUE 
}; 

vector<bool> arguablyVegetables(MAX_VALUE, false); 
arguablyVegetables[tomatoes] = true; 
arguablyVegetables[cucumbers] = true; 

cout << arguablyVegetables[apples] << endl; 
1

왜 논리적으로 또는 복수로 사용하기 위해 fruit_and_vegetables을 사용하지 않으시겠습니까? 에 저울 잘), 당신은 운영자 || 및 연산자 앞에 == 과부하, 뿐만 아니라 인수 및 결과 유형의 이전을 constexpr를 넣어 경우 , 다음 컴파일러는 컴파일시 코드 (아무 런타임 오버 헤드) 가능한 경우를 평가합니다 더 큰 a || b || c || c enum 범위를 사용하면 값을 대괄호 안에 넣을 수 있습니다.

#include <set> 
using std::set; 

enum fruit_and_vegetables 
{ 
    apples, 
    pears, 
    tomatoes, 
    cucumbers 
}; 

set<fruit_and_vegetables> operator||(fruit_and_vegetables left, fruit_and_vegetables right) { 
    set<fruit_and_vegetables> set; 
    set.insert(left); 
    set.insert(right); 
    return set; 
} 

set<fruit_and_vegetables> operator||(set<fruit_and_vegetables> left, fruit_and_vegetables right) { 
    left.insert(right); 
    return left; 
} 

set<fruit_and_vegetables> operator||(fruit_and_vegetables left, set<fruit_and_vegetables> right) { 
    right.insert(left); 
    return right; 
} 

bool operator!=(fruit_and_vegetables lhs, set<fruit_and_vegetables> rhs) { 
    return (rhs.find(lhs) == rhs.end()); 
} 

bool operator==(fruit_and_vegetables lhs, set<fruit_and_vegetables> rhs) { 
    return !(lhs != rhs); 
} 

int main() { 

fruit_and_vegetables fav = apples; 
if (fav == (apples || (pears || tomatoes))) cout << "match apples\n"; 
fav = cucumbers; 
if (fav == ((apples || pears) || tomatoes)) cout << "Error! matched ghost cucumbers\n"; 
if (fav != apples) cout << "correct no match apples\n"; 
if (fav == cucumbers) cout << "default operator==(FaV, FaV) match\n"; 
if (fav == (pears || apples)) cout << "yummi\n"; 

return 0; 
} 
관련 문제