gpt4 book ai didi

c++ - 删除 C++ 中的重复模式

转载 作者:行者123 更新时间:2023-11-30 01:00:33 25 4
gpt4 key购买 nike

我至少有 16 个以下形式的函数。

bool Node::some_walker( Arg* arg1 )
{
if(this == NULL)
return false;

bool shouldReturn = false;

if( this->some_walker_p(arg1, shouldReturn) ) //This line alone varies
return true;

if( shouldReturn ) // true is already returned
return false;

return this->std_walker(arg1);
}

函数 some_walker_p 是一个虚函数,我无法对其进行模板化。有什么解决方案可以避免这种代码重复吗?

谢谢,悟空。

最佳答案

这取决于私有(private)函数的参数是否相似。以下解决方案是可能的,从简单和有限到复杂和通用:

  1. 等价=<使用成员函数指针)
  2. 相同的数字,不同的类型 => 对每个参数进行模板化)
  3. 不同数量/类型的参数 => se boost::bind 和函数对象)

感谢您提出的意见。起初,我只发布了第一个解决方案,但还有(如所列)其他情况需要不同的方法。

成员函数指针:

bool Node::walker_caller(Arg* arg1, bool (Node::*memfn)(Arg*, bool))
{
...
if( (this->*memfn)(arg1, shouldReturn) ) //This line alone varies
return true;
...
}

bool Node::some_walker(Arg* arg1)
{
return walker_caller(arg1, &Node::some_walker_p);
}

bool Node::other_walker(Arg* arg1)
{
return walker_caller(arg1, &Node::other_walker_p);
}

旁注:我通常对 mem-fn-ptr 进行 typedef 以使语法更易于接受。

模板参数:

我假设你在这里总是有两个参数,但它们可以有不同的类型。

如果您的参数数量有限(比如 1 和 2),您可以实现 walker_caller 两次,一个用于一个参数,一个用于两个参数,两者都是模板化的。

template<class A1, class A2)
bool Node::walker_caller(A1 arg1, A2 arg2, bool (Node::*memfn)(A1, A2, bool))
{
...
if( (this->*memfn)(arg1, arg2, shouldReturn) ) //This line alone varies
return true;
...
}

bool Node::some_walker(Arg* arg, OtherArg* other_arg)
{
return walker_caller(arg, other_arg, &Node::some_walker_p);
}

bool Node::other_walker(OtherArg* other_arg, YetAnotherArg* yaa)
{
return walker_caller(other_arg, yaa, &Node::other_walker_p);
}

函数对象:

如果你的 walkers 使用不同的数字和参数类型,你可能想使用 boost::bind,也许还有 boost::function。 (不需要使用后者,但会减少生成的代码大小...)

// faster code, as the function object may be inlined, but
// each call instantiates a different walker_caller, so exe might be bigger
template<class F>
bool Node::walker_caller(const F& fn)
{
...
if( fn(shouldReturn) ) //This line alone varies
return true;
...
}

// only one implementation, so smaller foot print but
// all arguments need to be copied into a function objet
// which may be a perf hit if the arguments are big
// (this version is good to have when you inherit from Node...)
bool Node::walker_caller(const boost::function<bool (bool)>& fn)
{
...
if( fn(shouldReturn) ) //This line alone varies
return true;
...
}

bool Node::some_walker(Arg* arg1)
{
return walker_caller(boost::bind(&Node::some_walker_p, this, arg1, _1));
}

bool Node::other_walker(Arg* arg1, OtherArg* arg2)
{
return walker_caller(boost::bind(&Node::some_walker_p, this, arg1, arg2, _1));
}

关于c++ - 删除 C++ 中的重复模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2393874/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com