1

有没有一种很好的方法可以将以下代码简化为带有 C++ 和潜在提升库的单行代码。我基本上有一个以 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 示例,我很想看看它以供将来参考。

提前致谢。

4

2 回答 2

2

至少从外观上看,您可能希望使用 anstd::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::setor std::map,而不是在添加之前搜索以查找该项目是否已经存在,只需使用 insert ,如果具有该键的项目已经存在,它将失败(但如果标题添加是新的)。由于我们已经看过 using std::map,让我们考虑一下使用 set 的样子:

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(同样适用于std::mapvs. std::unordered_map)。

于 2013-02-13T00:52:57.913 回答
1

在带有 boost 的 C++ 中,您应该能够执行以下操作:

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

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

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

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

于 2013-02-13T22:54:59.430 回答