(C ++ Boost)在列表中查找成员与搜索词匹配的项目

时间:2013-02-13 00:43:03

标签: c++ boost find

有没有一种很好的方法可以将以下代码简化为使用C ++和可能的boost库的单行代码。我基本上有一个消息列表,其中title()作为成员函数。我想知道列表中是否存在具有给定标题的消息。

std::string title = "some title";
bool unique = true;

BOOST_FOREACH(Message& m, messages) {
    if (m.title() == title) {
        unique = false;
        break;
    }
}

如果您熟悉C#Linq,下面的C ++版本会很棒:

unique = (messages.FirstOrDefault(m => m.title() == title) == null);

不幸的是我不能使用C ++ 11,但是如果你有一个C ++ 11的例子,我很想看到它以供将来参考。

提前致谢。

2 个答案:

答案 0 :(得分:2)

至少从外观上看,您可能希望使用std::map来存储按标题键入的消息:

std::map<std::string, Message> messages;

...在这种情况下,您的搜索会变成:

bool unique = messages.find(title) == messages.end();

如果您坚持进行线性搜索并希望在title成为Message成员的情况下维持当前状态,则可以执行以下操作:

bool unique = std::find(messages.begin(), messages.end(),
                        [title](Message const &m) { return m.title == title; }) 
                    == messages.end();

但是,你可能不想做上述任何事情。相反,你可能只想使用std::setstd::map,而不是在添加之前搜索项目是否已经存在,只需使用insert,如果带有该键的项目将会失败已存在(但如果标题是新的,则添加)。由于我们已经考虑过使用std::map,让我们考虑一下如何使用集合:

class Message {
    std::string title;
    // other stuff
public:
    bool operator<(Message const &other) const { return title < other.title; }
}:

std::set<Message> messages;

messages.insert(some_new_message);    // automatically unique

根据具体情况(如果您有很多消息,不关心它们的排序),您可能希望使用std::unordered_set而不是std::set(这同样适用于{{ 1}}与std::map)。

答案 1 :(得分:1)

在使用boost的C ++中,您应该可以执行以下操作:

bool unique = boost::find_if(messages, boost::bind( &Message::title, _1 ) == title) == messages.end();

在C ++ 11中使用Linq和boost,你应该可以这样写:

bool unique = boost::empty(LINQ(from(m, message) where(m.title() == title)));

您不能在C ++中使用相同的first_or_default,因为默认值不是空指针。