Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+上的模式匹配+;矢量_C++_Templates_Generics_Pattern Matching - Fatal编程技术网

C++ C+上的模式匹配+;矢量

C++ C+上的模式匹配+;矢量,c++,templates,generics,pattern-matching,C++,Templates,Generics,Pattern Matching,我有几个函数近似的形式 struct ins; enum class op_t { // ... }; std::vector<ins> optimise_addone(std::vector<ins> prog) { for (size_t i = 0; i < prog.size() - 1; i++) { auto &a = prog[i]; auto &b = prog[i + 1];

我有几个函数近似的形式

struct ins;
enum class op_t {
    // ...
};

std::vector<ins> optimise_addone(std::vector<ins> prog)
{
    for (size_t i = 0; i < prog.size() - 1; i++) {
        auto &a = prog[i];
        auto &b = prog[i + 1];
        if (a.code == op_t::SET && a.op.which() == 1 && boost::get<uint16_t>(a.op) == 1 && b.code == op_t::ADD) {
            a = make_ins(op_t::INC);
            prog.erase(prog.begin() + i + 1);
            i += 1;
        }
    }
    return prog;
}

std::vector<ins> optimise_storeload(std::vector<ins> prog)
{
    for (size_t i = 0; i < prog.size() - 3; i++) {
        auto &a = prog[i];
        auto &b = prog[i + 1];
        auto &c = prog[i + 2];
        auto &d = prog[i + 3];
        if (a.code == op_t::SET && c.code == op_t::SET && b.code == op_t::STORE && d.code == op_t::LOAD && a.op == c.op) {
            a = make_ins(op_t::DUP);
            b = make_ins(op_t::SET, c.op);
            c = make_ins(op_t::STORE);
            prog.erase(prog.begin() + i + 3);
            i += 3;
        }
    }
    return prog;
}
struct-ins;
枚举类运算{
// ...
};
标准::矢量优化添加(标准::矢量程序)
{
对于(大小i=0;i
他们每个人都取一个向量,找到它的一个修补子部分(大小为N),并以某种任意方式修改它

在我看来,应该有一种推广方法,使用模板或函数对象或类似的方法,但我自己看不到

最好的方法是什么?

高阶函数很好地解决了您的问题。下面是一个C++14解决方案

以下是最终界面的外观:

std::vector<int> v{1, 2, 3, 4, 5};
patchVector<2>(v, [](auto& a, auto& b){
    std::cout << a + b << " ";
});
std::向量v{1,2,3,4,5};
patchVector(v,[](自动和a、自动和b){

std::这看起来很好!非常感谢,但是,它似乎不允许我从向量中删除元素?(
prog.erase(…)
(在我的原稿中)有什么想法吗?您可以将迭代器传递到调用
f
的子集中的第一项。例如:
f(v.begin()+i,v[i+Is]…)
。然后可以在lambda中使用它作为第一个参数。实际上,不,这也不起作用?因为我需要执行
vec.erase(它)
我还没有对向量的引用。@LordAro:有很多方法可以解决这个问题。你可以将
vec
传递给
f
作为一个额外的参数,你可以传递一个函数对象,该函数对象给定一个迭代器调用
vec.erase
,或者你可以通过引用在lambda中捕获
vec
,我想这会有用的k、 冒着主观的风险,你认为哪一个最好?
template <typename Vector, typename F, std::size_t... Is>
auto callWithSlice(std::size_t i, Vector& v, F&& f, std::index_sequence<Is...>)
{
    return f(v[i + Is]...);
}

template <std::size_t N, typename Vector, typename F>
auto patchVector(Vector v, F&& f)
{
    for(std::size_t i = 0; i < v.size() - N + 1; ++i)
    {
        callWithSlice(i, v, std::forward<F>(f), std::make_index_sequence<N>{});
    }
}