2013-03-11 3 views
2

대소 문자를 구분하지 않고 비교하여 Remove_If를 사용하는 방법을 보여 줄 수 있습니까? 어떻게 .. 또는이보다 그 일을 적어도 더 나은 방법 ... 그냥 추한 외모 나 remove_if들과 함께이 작업을 수행 할 수Remove_If 문자열에서 대소 문자를 구분하지 않음

template<typename T> 
struct is_literal 
{ 
    enum{value = false}; 
}; 

template<> 
struct is_literal<char> 
{ 
    enum{value = true}; 
}; 

template<> 
struct is_literal<char*> 
{ 
    enum{value = true}; 
}; 

template<> 
struct is_literal<const char*> 
{ 
    enum{value = true}; 
}; 

template<typename Char, typename Traits, typename Alloc> 
struct is_literal<std::basic_string<Char, Traits, Alloc>> 
{ 
    enum{value = true}; 
}; 

template<typename T> 
template<typename U> 
CustomType<T>& CustomType<T>::Delete(U ValueToDelete, bool All, typename std::enable_if<is_literal<U>::value, bool>::type CaseSensitive) 
{ 
    for (std::size_t I = 0; I < TypeData.size(); ++I) 
    { 
     if (CaseSensitive ? std::string(TypeData[I]) == std::string(ValueToDelete) : std::string(ToLowerCase(TypeData[I])) == std::string(ToLowerCase(ValueToDelete))) 
     { 
      TypeData.erase(TypeData.begin() + I); 
      if (!All) 
       break; 
      --I; 
     } 
    } 
    return *this; 
} 

을 모두 내가 결정 :

현재 내가 좋아하는 그것을 할 코드를 최적화하여 생각해 보았습니다.

if (CaseSensitive) 
{ 
    if (All) 
    { 
     TypeData.erase(std::remove(TypeData.begin(), TypeData.end(), ValueToDelete), TypeData.end()); 
    } 
    else 
    { 
     TypeData.erase(std::find(TypeData.begin(), TypeData.end(), ValueToDelete)); 
    } 
} 
else 
{ 
    //Do I have to forloop and lowercase everything like before then compare and remove? OR can I do it just like above using std::remove or std::find with some kind of predicate for doing it? 
} 

아이디어가 있으십니까?

답변

4

remove_if이 술어 인수를 취하는 때문에 글쎄,이 람다 꽤 쉽게해야합니다 : 당신이

struct StringEqualityPredicate { 

    std::string str; 
    bool caseSensitive; 

    StringEqualityPredicate(const std::string& str, bool caseSensitive = true) : str(str), caseSensitive(caseSensitive) 
    { } 

    bool operator(const std::string& str) 
    { 
     if (caseSensitive) { 
      //... 
     } else { 
      //... 
     } 
    } 

}; 

std::erase(std::remove_if(v.begin(), v.end(), StringEqualityPredicate(targetVal, caseSensitive)), v.end()); 

를 사용하고 있기 때문에 : 당신은 상태를 유지하는 구조체를 사용할 수

std::remove_if(TypeData.begin(), TypeData.end(), 
    [&ValueToDelete](U &val){ return ToLowerCase(val) == ToLowerCase(ValueToDelete); }); 
+0

이 람다는 G ++이 매우 긴 템플릿 오류를 일으키게합니다. 나는 이것을 받아 들인다. 왜냐하면 나는 아이디어를 얻었고 나는 나의 용기를 위해 작동하는 람다를 쓸 것이다. – Brandon

2

C++ 11, 가능성이 더 작고 깨끗한 방법 (예를 들어 람다),하지만 내 C + + 11 지식은 기본적으로 존재하지 않는 .... :).

이 방법은 if ​​블록을 메서드에서 인라인 대신 이동시키는 것 외에는 많은 일을하지는 못했지만 둘 이상의 장소에서이 작업을 수행하는 경우 (아니면 그냥 조금 추상화하고 싶을 때)), 이것은 유용 할 수 있습니다.

관련 문제