2013-09-05 2 views
0

진부한 사과이 사이트가 잘못된 경우 제게 알려주십시오! 나는 누구 개선에 어떤 포인터를 던질 수 있는지 여부, 특정 std::map에 존재하는이 사용하는 것이 좋습니다 궁금하고 있는지 여부를 확인하는 함수를 작성했습니다C++ std :: map이 올바른 방법입니다.

.

std::map은 값에 대해 여러 데이터 유형을 허용합니다.

union Variants { 

    int asInt; 
    char* asStr; 


    Variants(int in) { asInt = in; } 
    Variants() { asInt = 0;} 
    Variants(char* in) { asStr = in; } 

    operator int() { return asInt; } 
    operator char*() { return asStr; } 

}; 

template<typename T, typename Y> 
bool in_map(T value, std::map<T, Y> &map) 
{ 
    if(map.find(value) == map.end()) { 
     return false; 
    }else{ 
    return true; 
    } 
} 

내가 다음 주에 사용할 수 있습니다

std::map<string, Variants> attributes; 

attributes["value1"] = 101; 
attributes["value2"] = "Hello, world"; 

if(in_map<std::string, Variants>("value1", attributes)) 
{ 
    std::cout << "Yes, exists!"; 
} 

어떤 도움이나 조언이 크게 감상 할 수있다. 이 규칙이나 표준을 준수하지 않으면 죄송합니다. 감사!

+4

'in_map()'함수가 복잡하다고 생각합니다! 본문은'return map.find (value)! = map.end(); '가되어야합니다. –

+0

@ DietmarKühl 안녕하세요, 저는'너무 복잡합니다 '라는 말의 의미를 이해하지 못합니다. – Phorce

+0

'in_map'은'const '에 의해 두 인수를 취해야하고 함수 본문은'return map.find (value)! = map.end();' – Praetorian

답변

3

필자의 함수에서 볼 수있는 가장 큰 문제는 결과 반복자를 버리고 있다는 것입니다.

지도에 키가 있는지 확인하는 경우 대다수의 시간에 관련 값을 검색/사용하고 싶습니다. 이 경우 함수를 사용하면 성능 저하를 피하기 위해 이중 검색을 수행해야합니다. 당신은 단지 키가 존재하는지 여부를 확인하는 경우 물론

auto it = map_object.find("key"); 
if (it != map_object.end()) 
    use(it->second); 
else 
    std::cout << "not found" << std::endl; 

: 나는 쓸모없는 조회를 피하기 위해 나중에 사용하기 위해 주변의 반복자를 유지, 단지 모두 함수의 사용을 피하고, 직접 테스트를 작성합니다 그리고 관련 가치에 관심이 없다면 함수는 훌륭하다. (다른 사람들이 주석에서 당신에게 말한 것을 고려해 보라.)하지만 유스 케이스가 상당히 제한되어 있으며 추가 기능에 가치가 없다고 생각한다. 당신은 할 수 :

if (map_object.find("key") != map_object.end()) 
    std::cout << "found, but I don't care about the value" << std::endl; 
+0

답장을 보내 주셔서 감사합니다. 그것은 단지 PHP에서'if (in_array (#, #)')를 가지고 있고 C++에'std :: map'을 사용하여 이것을 적용 할 수 있는지 알고 싶었습니다. 그리고 find를 실행 한 것처럼 보였습니다. 코드가 어떻게 보이는지 너무 확신하지 못했습니다. 조언을 주셔서 감사합니다. :) – Phorce

0

뉴욕 포인터를 개선에.

template<typename T, typename Y> 
bool in_map(T value, const std::map<T, Y> &map) 
{ 
    return map.find(value) != map.end(); 
} 

그리고 첫 번째 매개 변수 (단지 기본 설정)로 배치합니다. 또한 모든 것이 단일 행에 들어가기 때문에이 함수가 필요하지 않을 수도 있습니다.

반환되는 반복기를 버리고 있지만 사용하지 않으므로 문제가되지 않습니다.

이외에도 코딩 실습 측면에서이 모양이 괜찮습니까? 나는. Union을 사용하거나 구조체와 같은 다른 유형을 사용할 수 있습니까?

글쎄, char*은 데이터를 수정할 수 있다는 의미이므로 char*을 사용하는 것이 좋습니다. char*은이 포인터가 동적으로 할당되어 나중에 포인터가 delete[]이 될 수 있음을 의미합니다. 그리고 당신은 노조에서 소멸자를 사용할 수 없습니다. 텍스트를 변경할 수없는 경우 const char*을 사용할 수 있습니다. 그렇지 않으면 다른 데이터 유형을 사용할 수 있습니다. 또한 참조하십시오 Rule of Three

다음 문제 - 같은 위치에 char * 및 int를 배치하려고합니다. 즉, 포인터를 정수로 변환하려고하는 시점이 있음을 의미합니다.64 비트 플랫폼 포인터가 int에 맞지 않을 수도 있고, 그 중 절반 만 얻을 수 있기 때문에 나쁜 생각입니다.

또한 동일한 변수에 여러 값을 저장하려는 경우 어느 유형이 저장되어 있는지 나타내지 않습니다. 이를 위해서는 구조체에 묶음을 묶고 저장된 객체의 유형을 나타내는 필드 (struct에)를 추가해야합니다. 그러나이 경우에는 바퀴가 다시 만들어지게됩니다. 따라서 "보편적"유형을 저장하려는 경우 Boost.Any, Boost.Variant 또는 QVariant을 볼 수 있습니다. 이들 모두에는 BIG 외부 라이브러리가 필요합니다 (boost 또는 Qt).

if(in_map<std::string, Variants>("value1", attributes)) 

입력하면

0

나 방금 편의에서 대신 map.find 기능을 사용하려면 만드는 유형 이름 구문을 모두 입력, 나에게 조금 지나친 것 같다. 그러나, 컴파일러에 따라, 때로는 템플릿 매개 변수를 해석 할 수 있습니다 자동으로, 예를 들어, 비주얼 스튜디오이 허용됩니다 :이 경우

if(in_map(std::string("value1"), attributes)) 

을, 나는 char*을 대체하는 std::string 객체를 생성했다,하지만 난 호출에서 템플릿 정의를 완전히 제거했기 때문에 컴파일러는 주어진 매개 변수를 기반으로 TY이 무엇인지 파악합니다.

그러나 내 권장되는 조언은 #define을 사용하여 "기능"을 정의하는 것입니다. 정말 기능은 아니지만 #define 실제로 단지 직접 소스에 코드의 조각을 대체하기 때문에, 그것은 일을 훨씬 쉽고 시각적으로 만들 수 있습니다

#define in_map(value,map) (map.find(value) != map.end()) 

그런 다음 코드를 그냥 다음과 같을 것이다 그것을 사용하는 :

if(in_map("value1", attributes)) 

둘 다 함수 호출을 사용하지 않는 최적화와 PHP에서와 같은 시각적 모양을 얻습니다.

+0

보통 정의는 악의적 인 http : //www.parashift입니다.co.kr/C++ - faq/inline-vs-macros.html – Amadeus

관련 문제