【问题标题】:Can we return a function in C++?我们可以在 C++ 中返回一个函数吗?
【发布时间】:2015-07-15 03:09:07
【问题描述】:

我有一个包含三个函数的程序:main()returnFunction()functionToBeReturned()main() 必须致电 returnFunction()。我们可以使用functionToBeReturned()作为returnFunction()的返回值吗?

int functionToBeReturned()
{
    // some code here....
    return value;
}

int returnFunction()
{
    // some code here....
    return functionToBeReturned();
}

int main()
{
    returnFunction();
}

这样好吗……

【问题讨论】:

  • 出于好奇,您尝试过吗?
  • 目前,returnFunction 返回与functionToBeReturned 相同的内容,即。 value(并且要获得valuereturnFunction 调用functionToBeReturned)。如果您想返回 functionToBeReturned 以便可以在 main 中调用它,那是不同的(但也可能)
  • @-deviantfan 假设我将 functionToBeReturned() 声明为布尔返回类型函数。现在 functionToBeReturned() 正在传递一个布尔值。 returnFunction() 仍然是 int 类型。然后呢?
  • @user5117637 然后returnFunction 调用functionToBeReturned 得到bool,然后自动转换为int(它是更大的类型等,在这里没问题),然后它s 回来了。布尔值 true 将是 1,false 0。关于返回函数本身,如果这是你想要的,请参阅下面的 brenns 答案。
  • 如果您的签名都相同,那么使用函数指针很容易。如果没有,您可以将 closures 与 C++11 std::functionboost::function 一起使用。否则你也有 libsignals++

标签: c++


【解决方案1】:

在 C 中,您可以拥有和返回函数指针;它们基本上指向您可以调用的机器代码。您可能有一些库函数能够“创建”函数(例如,动态生成或加载一些机器代码)并提供指向新创建代码的指针(dlsym,JIT 库,....) 但是,在纯标准 C99 或 C11 或 C++11 中,无法在运行时创建原始纯函数(在机器代码级别)。在受限于标准 C++ 或C 的程序中,函数集是固定的(并且是所有指针函数可以获得的值集,除了NULL 指针)。由于 C 缺乏适当的闭包,许多 C 框架(例如 GTK 或其 Glib、libevent、....)处理 callbacks,由 convention 混合函数指针和客户端实现数据(例如,读取GTK tutorial,参见g_signal_connect,...)

在 C++(C++11 或更高版本)中,您还可以拥有 closures、匿名函数(即 lambda-s)和 std::function;例如

 std::function<int(int)> translation(int delta) {
    return [delta](int x) { return x + delta; };
 }

在返回的闭包中(它在语义上几乎表现得像一个函数,因为您可以调用和应用它),delta 是一个封闭值。

闭包是一个极其重要和困难的概念,与lambda calculusfunctional programming 有关。需要数周时间才能理解它,不要感到惊讶。另见SchemeLisp In Small PiecesSICP....

This answer 与非常相似的question 提供了更多详细信息。

在机器级别,C 或 C++ 函数指针通常是指向 code segment 的某个地址,但 C++ 闭包是一些内部对象(属于某些“匿名”类,在您的编译器实现内部)混合代码指针和封闭值或引用。

学习一些函数式编程语言,例如 Ocaml、Scheme、Clojure、Haskell 或 Common Lisp,可以提高你的思维能力(即使是用 C 或 C++ 编码)。

【讨论】:

    【解决方案2】:

    是的!函数指针是 C 和 C++ 的一部分。使用函数指针,您可以从其他函数返回函数,并将它们存储在类中等。Here 是关于它们的文章。

    #include <iostream>
    using namespace std;
    int functionToBeReturned() {
        cout << "hello!" << endl;
    }
    int (*returnFunction())() {
        // Observe how the parentheses around returnFunction distinguish a function
        // returning a function pointer from a normal function.
        return functionToBeReturned;
    }
    int main() {
        int (*function)();
        function = returnFunction();
        function();
    }
    

    在这个程序中,returnFunction 是一个不接受任何内容并返回一个不接受任何内容并返回一个 int 的函数。涉及函数指针的声明在 C 和 C++ 中真的很难看!为了清楚起见,您可以考虑这样做:

    typedef int (*returns_int_t)();
    

    这为指向函数的指针定义了名称returns_int_t,该函数不接受任何内容并返回一个int。然后,你可以这样做:

    #include <iostream>
    using namespace std;
    
    typedef int (*returns_int_t)();
    
    int functionToBeReturned() {
        cout << "hello!" << endl;
    }
    returns_int_t returnFunction() {
        return functionToBeReturned;
    }
    int main() {
        returns_int_t function = returnFunction();
        function();
    }
    

    完全相同的事情。

    【讨论】:

    • 返回函数指针与返回函数本身不同(这在 C++ 中是不合法的)。在实践中,使用函数对象(std::functionstd::bind、lambdas)比使用函数指针更有用。
    • 非常好!我最近使用的 C 比 C++ 多得多,所以我习惯了减少的功能集。
    猜你喜欢
    • 2020-09-17
    • 2018-09-18
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多