将临时修改的向量传递到函数
Pass a temporarily modified vector to a function
在回溯问题中,我必须以在每个级别修改向量的方式将向量传递到函数:
void function(std::vector <int> vec){
vec.push_back(0); // Initial modification
function(vec);
vec.pop_back(); // Return to previous state
vec.push_back(1); // Second modification
function(vec);
return;
}
我省略了无关的代码。
有什么方法可以简化矢量修改,以便我不必以后pop_back?
您可以创建 guard 类,该类在破坏时自动调用 pop_back
:
template <typename T>
class push_pop_guard
{
private:
std::vector<T>& _v;
public:
template <typename Item>
push_pop_guard(std::vector<T>& v, Item&& x) : _v{v}
{
_v.push_back(std::forward<Item>(x));
}
~push_pop_guard()
{
_v.pop_back();
}
};
用法示例:
void function(std::vector <int> vec)
{
{
push_pop_guard ppg{vec, 0};
function(vec);
}
// ...
}
您可以将值传递给方法,然后将其推到向量:
:void function(std::vector <int> vec, int element){
vec.push_back(element);
//Do stuff
function(vec,0);
function(vec,1);
return;
}
我发现您所拥有的已经相当可读。我只能提高两点。
首先,首先是通过引用传递矢量,避免冗余副本。
其次,要维护回溯不变性,您仍然需要维护pop_back
。但是您可以将其移至一个不太尴尬的地方:
void function(std::vector<int> &vec){
vec.push_back(0); // Initial modification
function(vec);
vec.back() = 1; // Second modification
function(vec);
vec.pop_back(); // Return to previous state
return;
}
由于该函数会弹出它推出的整数,因此我们可以确定vec.back()
是呼叫之间的整数。因此,您可以执行简单的作业,而不是另一对pop并推动。
template<class F>
struct scope_guard_t {
std::optional<F> f;
scope_guard_t( F in ):f(std::move(f)) {}
scope_guard_t( scope_guard_t&& o ):
f(std::move(o.f))
{
o.clear();
}
void abandon() { clear(); }
void commit_early() { commit(); clear(); }
~scope_guard_t() { commit(); }
private:
void commit() { if(f) (*f)(); }
void clear() { f = std::nullopt; }
};
template<class F>
scope_guard_t<F> scope_guard( F in ) { return {std::move(in)}; }
template<class C, class T>
auto temp_push( C& c, T&& t ) {
c.push_back( std::forward<T>(t) ); // do
return scope_guard(
[&]{ c.pop_back(); } // undo
);
}
void function(std::vector <int> vec){
{
auto scope = temp_push( vec, 0 );
function(vec);
}
{
auto scope = temp_push( vec, 1 );
function(vec);
}
}
std::optional
可以在C 14和之前的boost::optional
替换。
scope_guard
通常很有用。
我还会通过参考传递来替换通过值传递的vector
;这可能会更有效,因为它避免了每次递归的重新分配。
相关文章:
- 函数向量_指针有不同的原型,我可以构建一个吗
- 如何使用向量的template_back函数
- 如何通过派生类函数更改基类中的向量
- 变量没有改变?通过向量的函数调用
- 一对向量构造函数:初始值设定项列表与显式构造
- 在c++中使用向量时,如何调用构造函数和析构函数
- std::sort()函数无法对向量的一部分进行排序
- 如何在C++向量中奇数元素前面加上值-1,我在使用insert函数时遇到了问题
- C++中函数的向量返回类型引发错误
- 添加存储在向量中的大整数的函数出现问题
- 如何在 c++ 中定义接受不同参数类型的函数向量?
- 具有 lambda 函数的函数向量
- 你能用参数制作函数向量吗?
- 在C++中使用成员函数向量时,有没有办法实现协变返回类型
- 在编写 lambda 函数向量时出现隔离错误
- 如何在 boost.process 间共享内存中使用复杂结构"push_back"函数向量
- 是否将std矢量重新分配到默认的构造函数向量是擦除的好方法
- 运行提升for_each中的成员函数向量
- 创建和回推函数向量
- C++,指向函数向量的指针的STL映射