【问题标题】:pass function by value (?) instead of function pointer?通过值(?)而不是函数指针传递函数?
【发布时间】:2011-10-29 23:43:08
【问题描述】:

抱歉,之前有人问过这个问题,但我找不到。

所以我试图让自己了解模板和新的 C++11 功能(主要是 lambda,我一直喜欢其他语言的东西)。

但在我的测试中,我发现了一些我不知道它有效的东西,我试图了解它是如何工作的,但无法弄清楚..

以下代码:

template <class Func>
void Test( Func callback ) {
    callback( 3 );
}

void Callback( int i ) {
    std::cout << i << std::endl;
}

int main( int argc, char** argv ) {
    Test( &Callback ); // this I was expecting to work, compiler will see its a pointer to a function
    Test( Callback ); // this also works, but how?!
    return 0;
}

如果我了解模板的工作原理,基本上它们是编译器知道要构建什么的方案,所以我希望第一次调用Test( &amp;Callback ); 可以工作,因为编译器会看到模板接收到一个函数地址并将假设参数应该是一个指针。

但是第二个电话是什么?假设它是什么模板?一个函数的副本(如果这有任何意义的话)?

【问题讨论】:

    标签: c++ function templates c++11


    【解决方案1】:

    函数可以隐式转换为指向自身的指针;这种转换几乎无处不在。 Test(Callback)Test(&amp;Callback) 完全相同。没有区别。在这两种情况下,Func 都被推断为void(*)(int)

    函数指针很奇怪。你可以在"Why do all these crazy function pointer definitions all work?"了解更多关于他们的信息

    【讨论】:

    • 感谢您的回答。因此,如果我没有使用模板并声明 Test 如下: void Test( void (*callback)(int) ){...} 两个调用也可以正常工作。很高兴知道。请确保我阅读了您链接的主题。
    【解决方案2】:

    在 C++ 中,函数不是一等对象,这意味着“函数作为值”在其中毫无意义。这就是为什么函数名总是可以隐式转换为指向它的指针。

    【讨论】:

    • 也许值得一提的是,有些语言的“按值函数”确实有意义。
    【解决方案3】:

    函数可以隐式转换为函数指针。如果事实上没有办法获得函数值或引用。虽然奇怪的是你可以创建一个函数值类型,但你不能给它分配任何东西。

    Here is code snippit 演示了 lambda 和各种回调如何与模板发生反应。

    【讨论】:

    • 这是错误的。函数引用很好。如果Test 被声明为void Test( Func &amp;callback ),那么Func 将被推导出为void(int),而Callback 将通过引用传递给Test,而不转换为指针。
    • 哇!我想应该支持引用以及指针是有道理的,因为它们非常相似。是否可以声明一个函数值并为其赋值?
    • @deft 我不知道那是什么意思。什么是“函数值”?
    【解决方案4】:

    在 C++ 11(以及 boost 和 tr1)中,我们将 std::function 作为模板类型,用于存储仿函数、lambda 和函数。因此,您绝对可以拥有将函数值保存在 std::function 类型的变量中的概念。该变量也可以是“空的”,这意味着其中没有存储函数(引用)。那么就不能调用了。

    最初的问题与 C 相比,C++ 允许函数引用。另外,出于与 C 的兼容性原因,函数名可以退化为函数指针。但是由于重载,C++ 中的东西比 C 中的更“有趣”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-16
      • 1970-01-01
      • 1970-01-01
      • 2018-06-04
      • 2021-06-24
      • 1970-01-01
      • 1970-01-01
      • 2010-09-29
      相关资源
      最近更新 更多