std :: remove_if不会删除所有项目

时间:2015-10-19 18:29:44

标签: c++ algorithm

在输入中,我想删除所有非唯一值。删除双项后,我想要子集与输入相同。不知何故,某些字符仍保留在输入中,并且不会删除所有字符。看起来谓词中的std :: map的大小也在递减。

我使用的std :: remove_if()的谓词是:

template<class T>
class RemovePredicate {

    public:

        RemovePredicate() : m_oldsize(0) {}

        bool operator()(const T& value)
        {
            //
            bool retval;
            m_uniques[value] ='a'; // 'a' could be any value
            cout << m_uniques.size() << endl;
            retval = m_uniques.size() == m_oldsize;
            m_oldsize = m_uniques.size();
            return retval;
        }

    private:

        std::map<T, char>   m_uniques;
        unsigned            m_oldsize;

};

我以这样的方式设计了谓词,当我看到大小增加时,我没有遇到输入。因此,当尺寸不同时,我不会删除输入。当尺寸保持不变时,我再次遇到了输入值,然后我将其删除。

测试它的代码是:

template<class T>
void print(T iterable)
{
    for (auto c : iterable)
        cout << c;
    cout << endl;
}


int main(int argc, char** argv){
    if (argc != 2)
        return 1;

    char * str= argv[1];

    vector <char> charvec (str, str + strlen(str));
    print(charvec);

    auto itend = std::remove_if(charvec.begin(),
                                charvec.end(),
                                RemovePredicate<char>()
                                );
    print(charvec);
    // apply erase remove idiom
    charvec.erase(itend, charvec.end()); 
    print(charvec);
    return 0;
}

示例输入是:

  

./ remove_duplicates deadbeef

输出

  

deabef

但正如你所看到的那样,仍然有一个双重的&#39;输出内部。但从好的方面来看,原始的顺序是保持不变的。

我做错了什么?

1 个答案:

答案 0 :(得分:4)

无法保证对谓词的每次调用都是在函数对象的同一副本上进行的。

您需要安排副本共享一个map(或setunordered_set),例如通过在更广的范围内声明map并保留引用,或者使用shared_ptr(因此函数对象作为一个组仍然拥有它)。