繁体   English   中英

c ++作为没有指针的参数

[英]c++ functions as parameters without pointers

在搜索如何在C ++中将函数作为参数传递时,我只找到使用函数指针的示例。 但是,以下内容在Visual Studio中按预期编译并输出“g20”。 这样声明f更好吗:

f(void (*fun)());

代替

f(void fun());

我的例子:

#include <iostream>

using namespace std;

int f(void fun());
void g();

int main() {
    cout << f(g);
}

void g() {
    cout << "g";
}

int f(void fun()) {
    fun();
    return 20;
}

您可能更喜欢std::function<>而不是函数指针。 它不仅可以存储函数指针,还可以存储lambdas,绑定表达式,函数对象(带有operator()对象)等。特别是lambdas将使您的API更好用。

int f(std::function<void()>& fun) {
    fun();
    return 20;
}

另一种简单且没有std:::function成本的std:::function是使用模板。

template <typename Function>
int f(Function function) {
  function();
  return 20;
}

这样,类型将被推断为任何类型的可调用对象。 它还应该使编译器能够内联调用(如果可以的话)(使用std::function是不可能的)。

两种形式都是等同的。 我更喜欢明确显示参数是指针的表单。 参数是指针的知识很重要,因为您可以将值NULLnullptr0作为参数传递。 您的程序将编译,但如果有人将执行函数调用f(0)则会崩溃。 在调用指针对象之前,您总是希望检查函数指针是否不是空指针,除非您确定使用NULLnullptr0参数调用函数是不可能的。

如果在项目中使用lambdas,则应使用`templates。 否则你可以继续使用原始函数指针,但要确保检查函数指针(如果需要)

template <typename Function>
int f(const Function& functionp) {
  if(functionp)
     functionp();
  return 20;
}

Lambdas和std::function<>对象也有一个bool运算符,所以行if(functionp)也适用于那些。 它将对包含nullptr的std::function<>对象求值为false ,否则对std::function<>对象和lambdas求值为true

Ampersand &使其成为引用, std :: decay_t使引用成为指针。

template <class R, class Args...>
using func_ref_t = R(&)(Args...)

template <class R, class Args...>
using func_ptr_t = R(&)(Args...)

根据C(和C ++)标准,当参数具有函数类型时,编译器会自动将其调整为相应的函数指针类型。 因此,就编译器而言,两者是相同的。

C99标准第6.7.5.3节第8段:

参数声明为''函数返回类型''应调整为''函数返回类型的指针'',如6.3.2.1所述。

C ++ 03标准第8.3.5节第3段:

[...]确定每个参数的类型后,任何类型[...]“函数返回T”的参数分别被调整为“指向函数返回T的指针”。 [...]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM