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

标签 c++ templates virtual

我至少有 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/

相关文章:

c++ - 检查 Makefile 中使用的 g++ 版本

c++ - 错误 c2440 '=' 无法从 int * 转换为 Type<T> *

虚函数上的 C++ 多态性

c++ - 是否有可能确定/断言,如果一个虚函数被覆盖,另一个虚函数也被覆盖?

C++:原始类型的 iostream operator<< 和 operator>> 是虚拟的吗?

c++ - 无法加载 64 位 dll

c++ - 统一初始化以调用初始化程序列表以外的构造函数

c++ - 带有模板关键字的伪析构函数调用

Django 模板缩进指南

c++ - 访问 CUDA 中的结构成员?