c++ typeSpecifier functionPointer = & definedFunction和typeSpecifier functionPointer = definedFunction有什么区别?

z9zf31ra  于 2023-08-09  发布在  其他
关注(0)|答案(2)|浏览(84)

请首先考虑以下示例(这是来自Cplusplus.com的代码的一部分):

#include <iostream>     // std::cout
#include <functional>   // std::function, std::negate

int half(int x) {return x/2;}

int main () {
  std::function<int(int)> fn1 = half;                    // function
  std::function<int(int)> fn2 = &half;                   // function pointer
  std::cout << "fn1(60): " << fn1(60) << '\n';
  std::cout << "fn2(60): " << fn2(60) << '\n';
  return 0;
}

字符串
例子中fn 1和fn 2有什么区别?
这是否意味着fn 1将复制函数“一半”,而fn 2只是指向该函数。www.example.com的评论Cplusplus.com暗示它们是不同的;但我从一些视频中听说它们是一样的,运算符“&”只是可选的。
那么真相是什么呢?请帮帮忙。

mzmfm0qo

mzmfm0qo1#

如果typeSpecifier是一个对象,则在大多数情况下没有实际的区别。在您的程式码中,使用half&half的作用完全相同。仍然值得注意的是,其中涉及两种不同的影响:

函数到指针的转换

auto f = function;

字符串
这会胁迫将function隐含转换为对象,称为 * 函式至指标 * 转换:
函数类型T的左值可以转换为类型为“指向T的指针”的右值。结果是指向函数的指针。

  • [转换函数] p1
    请注意,您的程式码不会明确执行 * 函式至指标 * 的转换,因为您会隐含呼叫下列建构函式:
// You end up calling this with F = int(&)(int)
// i.e. a reference to a function taking int and returning int.
// (See https://cdecl.plus/?q=int%28%26%29%28int%29 for learning type syntax)
template<class F>
function(F&& f);


此构造函数使用std::decay_t并在内部执行 * 函数到指针的转换 *。

使用&获取函数的地址

auto f = &function;


这将显式获取函数的地址:
一元&运算子的算子应该是某种T型别的左值。其结果是一个正数值。

  • [...]
  • 否则,结果的类型为“pointer to T“,并指向指定的对象或函数。
  • [表达式一元运算符] p3
    在您的范例中,您仍然会呼叫上述的建构函式。不过,这次传入的是“函数指针”int(*)(int),而不是“函数引用”int(&)(int)。最终的结果是一样的。
flseospp

flseospp2#

实际上没什么区别。当我们从函数构造一个std::function时,函数的引用衰减为一个指针。
在看起来像复制的上下文中,引用会立即衰减为指针,就像在C中一样:

int main()
{
    auto f1 = half;
    auto f2 = &half;

    static_assert(std::is_same_v<decltype(f1),decltype(f2)>);
}

字符串

相关问题