2

大文字と小文字を区別しない比較で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

2 に答える 2

4

まあ、remove_if述語引数を取るので、これはラムダでかなり簡単なはずです:

std::remove_if(TypeData.begin(), TypeData.end(),
    [&ValueToDelete](U &val){ return ToLowerCase(val) == ToLowerCase(ValueToDelete); });
于 2013-03-11T01:03:39.387 に答える
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を使用しているので、よりコンパクトでクリーンな方法(たとえば、ラムダ)がありますが、私のC++11の知識は基本的に存在しません....:)。

これは、ifブロックをメソッド内でインラインではなく構造体に移動する以外は、実際にはあまり達成されていませんが、複数の場所でこれを実行している場合(または少し抽象化したい場合)は、これが可能です。役に立つ。

于 2013-03-11T01:04:15.117 に答える