c++ - 如何编写一个在没有任何条件的情况下也有条件(真假)的通用仿函数?

标签 c++

我有下面给出的三个仿函数。如果可能的话,我想把它们合二为一。我也给出了他们的用例。

struct ElemsCombine1 {
    Special s;

    Elems operator()(const Elems& acc, const auto& it) const
    {
        Special p = *it;
        Elems later_element;
        later_Element = this->l.get(p);
        Elems result;

        for (auto a : acc) {
            for (auto n : later_element) {
                result.push_back(a.join(n, s));
            }
        }
        return result;
    }
};

struct ElemsCombine2 {
    Special s;
    WtoN& turn;

    Elems operator()(const Elems& acc, const auto& it) const
    {
        Special p = *it;
        Elems later_element;
        later_Element = this->l.get(p);

        if (this->ab.net(p) <= turn) {
            Elems result;

            for (auto a : acc) {
                for (auto n : later_element) {
                    result.push_back(a.join(n, s));
                }
            }
            return result;
        }
        else return acc;
    }
};

struct ElemsCombine3 {
    Special s;
    WtoN& turn;

    Elems operator()(const Elems& acc, const auto& it) const
    {
        Special p = *it;
        Elems later_element;
        later_Element = this->l.get(p);

        if (this->ab.net(p) > turn) {
            Elems result;

            for (auto a : acc) {
                for (auto n : later_element) {
                    result.push_back(a.join(n, s));
                }
            }
            return result;
        }
        else return acc;
    }
};

target_fun(Wto& v)
{
    Special s = v.node();
    Elems initial_element;
    const WtoN& turn = this->cd.net(s);
    initial_element = this->m.get(s);
    auto comb1 = ElemsCombine1();
    comb1.s = s;
    Elems E = std::accumulate(pre_begin(s), pre_end(s), *initial_element, comb1);

    auto comb2 = ElemsCombine2();
    comb2.s = s;
    comb2.turn = turn;
    Elems E = std::accumulate(pre_begin(s), pre_end(s), *initial_element, comb2);

    auto comb3 = ElemsCombine3();
    comb3.s = s;
    comb3.turn = turn;
    Elems E = std::accumulate(pre_begin(s), pre_end(s), *initial_element, comb3);
}

请注意,三个仿函数 ElemsCombine1ElemsCombine2ElemsCombine3 之间的唯一区别是它们内部的 if 条件语句。请告诉我如何将 3 个仿函数合二为一。如果无法将不带 if 语句的仿函数 ElemsCombine1 与 if 语句仿函数 ElemsCombine2ElemsCombine3 组合,那也是可以接受的。

最佳答案

您可以使用仿函数分解代码,例如:

template <typename F>
struct ElemsCombine {
    Special s;
    F f;

    Elems operator()(const Elems& acc, const auto& it) const
    {
        Special p = *it;
        Elems later_element;
        later_Element = this->l.get(p);

        if (f(p)) { return acc; }
        Elems result;

        for (auto a : acc) {
            for (auto n : later_element) {
                result.push_back(a.join(n, s));
            }
        }
        return result;
    }
};

然后只需要 3 个条件仿函数(可能是 lambda):

struct always_false
{
    bool operator(const Special&) const { return false;}
};

struct Foo3
{
    WtoN& turn;

    bool operator(const Special& p) const { return this->ab.net(p) > turn;}

};

struct Foo2
{
    WtoN& turn;

    bool operator(const Special& p) const { return this->ab.net(p) <= turn;}
};

然后

ElemsCombine<always_false> ElemsCombine1{s};
ElemsCombine<Foo2> ElemsCombine2{s, {turn}};
ElemsCombine<Foo3> ElemsCombine3{s, {turn}};

关于c++ - 如何编写一个在没有任何条件的情况下也有条件(真假)的通用仿函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55949030/

相关文章:

c++ - 在 C/C++ 中通过 TCP 套接字发送十六进制

C++ MAPI RecipDesc 初始化

c++ - 为什么打印字符串数组只打印第一个字符?

C++ 多态、重载和继承

c++ 只继承公共(public)构造函数

c++ - 当它们大小相同时,将 vector<int> 转换为 vector<long> ?

c++ - 如何更改 Google Benchmark 'Range()' 函数的增量或步长或比例

C++ Int在不应该更改它的函数后获取随机值

c++ - 从 unsigned char* 到 char* 的无效转换

c++ - 查找 x^n 的所有组合并检查它们加起来是否为不包括相同数字的数字