You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向std::mismatch条件传递谓词以避免重复调用?

问题

调用多参数版本的std::mismatch时,需要根据条件二选一:要么使用标准默认比较逻辑,要么传入自定义谓词。要求:

  • 避免重复书写std::mismatch的完整调用代码
  • 优先采用简洁的内联实现
  • 高频执行的关键路径不能有额外的条件判断开销
  • 禁止使用多态谓词,必须复用标准库的默认比较逻辑,不依赖编译器内联优化来保证性能

现有可运行的实现代码:

#include <algorithm>
#include <iostream>
#include <vector>

struct some_functor {
    bool is_5_met = false;

    bool operator ()(auto lhs, auto rhs) {
        if (is_5_met) {
            return false;
        }

        if (lhs == 5 || rhs == 5) {
            is_5_met = true;
        }

        return lhs == rhs;
    }
};

auto some_function(const std::vector<int>& data, long offset, bool cond) {
    return cond
        ? std::mismatch(data.begin(), data.end(), data.begin() + offset, data.end(), some_functor()).first - data.begin() 
        : std::mismatch(data.begin(), data.end(), data.begin() + offset, data.end()).first - data.begin();
}


int main()
{
    std::vector<int> data = { 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7, };

    std::cout << "Without 5 as sentinel : " << some_function(data, 7, false) << "\n";
    std::cout << "With 5 as sentinel : " << some_function(data, 7, true) << "\n";
}

期望的简化写法(伪代码):

auto some_function(const std::vector<int>& data, long offset, bool cond) {
    return std::mismatch(data.begin(), data.end(), data.begin() + offset, data.end(), cond ? some_functor() : AND-DEFAULT-COMPARISON-HERE).first - data.begin();
}
解决方案

可以通过编译期分支或类型萃取的方式,在避免重复代码的同时保证关键路径无额外开销,以下是两种可行方案:

方案1:编译期分支封装(C++17+)

将std::mismatch的公共参数提取,用lambda封装编译期/运行期分支逻辑,避免重复书写完整调用:

#include <algorithm>
#include <iostream>
#include <vector>
#include <type_traits>

struct some_functor {
    bool is_5_met = false;

    bool operator ()(auto lhs, auto rhs) {
        if (is_5_met) {
            return false;
        }

        if (lhs == 5 || rhs == 5) {
            is_5_met = true;
        }

        return lhs == rhs;
    }
};

auto some_function(const std::vector<int>& data, long offset, bool cond) {
    auto begin1 = data.begin();
    auto end1 = data.end();
    auto begin2 = data.begin() + offset;
    auto end2 = data.end();

    auto result = [&]() {
        if (cond) {
            return std::mismatch(begin1, end1, begin2, end2, some_functor());
        } else {
            return std::mismatch(begin1, end1, begin2, end2);
        }
    }();

    return result.first - begin1;
}

int main()
{
    std::vector<int> data = { 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7, };

    std::cout << "Without 5 as sentinel : " << some_function(data, 7, false) << "\n";
    std::cout << "With 5 as sentinel : " << some_function(data, 7, true) << "\n";
}

如果cond是编译期常量,编译器会直接消除无效分支;即使是运行时变量,也不会在谓词内部产生额外判断,完全复用原生std::mismatch的两种实现路径。

方案2:编译期谓词类型选择(C++11+,适合编译期已知条件)

利用std::conditional和标准库的std::equal_to<>(与std::mismatch默认比较逻辑完全一致),在编译期确定谓词类型:

#include <algorithm>
#include <iostream>
#include <vector>
#include <functional>
#include <type_traits>

struct some_functor {
    bool is_5_met = false;

    bool operator ()(auto lhs, auto rhs) {
        if (is_5_met) {
            return false;
        }

        if (lhs == 5 || rhs == 5) {
            is_5_met = true;
        }

        return lhs == rhs;
    }
};

// 编译期选择谓词类型
template<bool Cond>
using PredType = std::conditional_t<Cond, some_functor, std::equal_to<>>;

auto some_function(const std::vector<int>& data, long offset, bool cond) {
    // 若cond为编译期常量,直接实例化对应谓词
    if constexpr (cond) {
        PredType<true> pred;
        auto result = std::mismatch(data.begin(), data.end(), data.begin() + offset, data.end(), pred);
        return result.first - data.begin();
    } else {
        PredType<false> pred;
        auto result = std::mismatch(data.begin(), data.end(), data.begin() + offset, data.end(), pred);
        return result.first - data.begin();
    }
}

int main()
{
    std::vector<int> data = { 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7, };

    std::cout << "Without 5 as sentinel : " << some_function(data, 7, false) << "\n";
    std::cout << "With 5 as sentinel : " << some_function(data, 7, true) << "\n";
}

此方案完全在编译期确定调用的std::mismatch版本,无任何运行时额外开销,且复用标准库默认比较逻辑,无需自行编写“平凡”谓词。

内容的提问来源于stack exchange,提问作者Damir Tenishev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 15:15:07