2013-03-11 99 views
2

有人可以告诉我如何使用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; 
} 

我想的remove_if一些做这怎么..或至少做比这更好的办法。它只是看起来丑陋的一切,我决定优化代码,所以我想出了:

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需要一个谓词的说法,这应该是一个拉姆达很简单:

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

此lambda导致G ++通过非常非常长的模板错误..关于char *&的一些东西。我接受这个,因为我明白了,我会写一个适用于我的容器的lambda。 – Brandon 2013-03-11 01:15:16

2

你可以使用保存状态的结构:

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()); 

由于您使用C++ 11,可能会有更简洁更干净的方式来做到这一点(例如lambda),但我的C++ 11知识基本上不存在.... :)。

虽然除了将您的if块移动到结构中而不是内联在您的方法中,但这并没有真正实现,但如果您发现自己在多个位置执行此操作(或者您只是想将它抽象化一点),这可能会有用。

相关问题