将一个函数的 vector + map 版本合并为一个兼容的版本

Merging vector + map Versions of a Function to a Single Compatible Version

这是我为 std::map 容器和 std::vector 容器使用 Lambda 表达式的两个重载函数。

有没有人看到一种使它成为模板函数的方法,它可以检查 pair 类型(在我的例子中是第二对)和常规范围类型(​​如 vector 的 Lambda 表达式, deque, 等等)。

bool isPlayerIn(vector<Player*> players, int id) {
    vector<Player*>::iterator found = find_if(begin(players), end(players),
                                              [id] (Player* player) {
        return player->getId() == id;
        });
     return found != end(players);
}

bool isPlayerIn(map<int, Player*> players, int id) {
     map<int, Player*>::iterator found = find_if(begin(players), end(players),
                                                 [id] (pair<int, Player*> found) {
        return found.second->getId() == id;
        });
     return found != end(players);
}

这可以通过一些 template metaprogramming, specifically something like Boost's is_pair 来解决。思路是"push down"从算法到函子的微分。

请注意,对于您编写的这种类型的非常短的函数,您可能不会发现这是一个改进;对于更长的函数,涉及更复杂的算法,这将消除大量重复。

所以,你会有两个 类 像这样:

template<typename T, bool Pair> 
matches_id : 
    std::unary_function<T, bool>
{
    // Ctor taking id
    // operator() deciding if t.second matches id
};

template<typename T>
matches_id<T, false> : 
    std::unary_function<T, bool>
{
    // Ctor taking id
    // operator() deciding if t itself matches id
};

在您的代码中,您将 find_if 与类型为

的对象一起使用
matches_id<T, is_pair<T>::value>