【问题标题】:Function Pointers by Reference引用的函数指针
【发布时间】:2017-05-30 22:51:32
【问题描述】:

大家好,我正在创建一个 List 类,以便能够像在 python 中一样操作数据,但在 c++ 中。 我想出了一个主意。基本上是一种遍历每个节点的方法,如果满足特定条件则将其删除。但我希望该条件由库的用户确定,因此我实现了一个指向 bool 函数的指针,该函数将一个模板数据(与 List 相同的类型)作为其唯一参数。

到目前为止,我设法运行了这个......


.h 文件:

int delIf(bool (*)(T));

.cpp 文件:

template <typename T>
int List<T>::delIf(bool (*ptr)(T)){
    int tot=0;
    T aux;
    for (int i=0;i<tam;i++)
    {
        aux=(*this)[i]; //Ive overloaded the [], and it works fine
        if ((*ptr)(aux))
        {
            tot++;
            this->del(i);
        }
    }
    return tot;
}

main.cpp:

#include <iostream>
#include "lists.cpp"

using namespace std;

bool check(int);

int main()
{
    List<int> a;
    for (int i=0;i<10;i++)
        a.push(i);
    a.delIf(&check);

    return 0;
}

bool check(int a){
    if (a%2==0)
        return true;
    else
        return false;
}

这很好用,但是,我想知道是否可以重载 delIf 方法,以便它不将指向函数的指针作为参数,而是对它的引用,因此库的用户可以调用:

delIf(check); //No '&' required

而不是

delIf( & check);

目前这是强制性的。我尝试将原型更改为:

int delIf(  (bool (*)(T)) & );

但我不断收到错误。

在此先感谢大家。

【问题讨论】:

  • “一种遍历每个节点的方法,如果满足特定条件则将其删除。但我希望该条件由用户确定”-听起来您正在重新发明std::remove_if - en.cppreference.com/w/cpp/algorithm/remove
  • 你的 check 函数可以写成更简单的 return a % 2 == 0;

标签: c++ pointers reference function-pointers pass-by-reference


【解决方案1】:

你的前提是错误的。您不需要在函数前面加上&amp; 即可将其传递给delIf。函数的名称几乎在表达式中使用的任何地方都衰减为指向该函数的指针。 (包括当你调用函数时!)事实上,它唯一没有的地方是它被用作&amp; 的参数 - 所以

func
&func

具有完全相同的类型和值。

话虽如此,是的,您可以传递参考。函数指针的第一条规则 - 编写 typedef

typedef bool pred_t(T);
void delIf( pred_t& pred );

但是!我强烈建议您将delIf 编写为函数模板,并允许任何可以用T 调用的东西,并且具有可以隐式转换为bool 的函数结果。

template <typename Pred>
void delIf(Pred pred) {
   ...
}

这将允许与捕获 lambdas 和一般函子一起使用。

另外,您所说的这个 CPP 文件是什么?模板必须在头文件中实现。查看this question的答案。

(注意:“Pred”是“predicate”的缩写,标准称之为此类函数。)

【讨论】:

  • Templates have to be implemented in the header file. 也许 OP 正在将他的 .cpp 包含在他的 .h 中
  • The name of a function decays into a pointer to the function ...
  • 标准的第 4 节(“标准转换”)特别是 4.3(函数到指针的转换)是权威来源。这个answer 在标准语言中看起来非常详细。
  • 或者找一本好的 C 或 C++ 书籍(这种转换存在于 K&R C 中 - 事实上它很可能存在于 BCPL 中)。
  • "包括调用函数的时候!" - 仅在 C 中! C++ 的内置 operator() 接受左侧的函数左值。
猜你喜欢
  • 2013-10-12
  • 2021-09-08
  • 2011-09-26
  • 2011-06-17
  • 1970-01-01
  • 2019-07-18
  • 1970-01-01
  • 2020-08-12
  • 1970-01-01
相关资源
最近更新 更多