如何对接受函数地址的参数进行默认参数?

How to make a default argument to parameter which takes function address?

提问人:Kesto2 提问时间:6/11/2023 最后编辑:JeJoKesto2 更新时间:6/12/2023 访问量:112

问:

我将如何制作一个将另一个函数的地址作为参数的函数,这样就不需要传递它了。

我的第一个解决方案是这样的:

void empty_func() {}

void func(void (*additional_func) () = &empty_func)
{
    additional_func();
    // some other code...
}

此解决方案有效。

但是,我想知道有没有更方便的方法可以使传递成为可选的,因此我不必创建一个新函数()并将其作为默认参数传递?additional_functionempty_func()

C++ 参数 函数指针 default-parameters

评论

0赞 n. m. could be an AI 6/11/2023
nullptr(此空格故意留空)
4赞 G.M. 6/11/2023
非捕获 lambda:?void func(void (*additional_func)() = []{})
1赞 πάντα ῥεῖ 6/11/2023
对于函数参数,首选和 nop lambda () 作为默认值。std::function<void ()>[]{}

答:

6赞 JeJo 6/11/2023 #1

我想知道有没有更方便的方法可以使传递additional_function成为可选的,这样我就不必创建一个新函数()并将其作为默认参数传递?empty_func()

您可以通过使用大括号提供默认参数来做到这一点:

// alias type for function pointer type
using FunPtr = void (*) (); 

void func(FunPtr additional_func = {})
//                                 ^^^
{
    if (additional_func)
       additional_func();    
       // some other code...
}

但是,这会导致在函数指针调用之前进行 nullptr 检查,这使得上述方法不是一个方便的解决方案。

幸运的是,还有另一种选择。非捕获 lambda 可以分配给普通函数指针类型,通过该类型,我们可以确保有默认调用的内容,因此没有空检查。

using FunPtr = void (*) ();
void func(FunPtr additional_func = []{})
//                               ^^^^^^
{
    additional_func();
}
3赞 cse 6/11/2023 #2

由于函数指针也是一个指针,因此指针类型与 null 等效,因此您可以将此默认参数的值赋值为 。nullptrnullptr

另外,不要错过在使用前忘记添加检查。nullptr

void func(void (*additional_func) () = nullptr )
{
    if(additional_func)
    {
        additional_func();
    }

    //some other code...
}

此外,为该函数指针定义别名更方便,如下所示:

using TPFunc = void (*) ();

void func( TPFunc additional_func = nullptr )
{
    if(additional_func)
    {
        additional_func();
    }

    //some other code...
}

但最好使用函数头文件中的功能,而不是这些原始函数指针。以下是使用头文件实现此目的的示例:functional

#include <iostream>
#include <functional>
 

using TPFunc = std::function<void()>;

void func( TPFunc additional_func = nullptr )
{
    if(additional_func)
    {
        additional_func();
    }
    else
    {
        std::cout<< "Function pointer is `nullptr`\n";
    }

    //some other code...
}


void fun1()
{
    std::cout << "In 'void fun1()'\n";
}


void fun2()
{
    std::cout << "In 'void fun2()'\n";
}

int main()
{
    func();
    func(fun1);
    func(fun2);
    std::cout<< "Done";
    return 0;
}

输出:

Function pointer is `nullptr`
In 'void fun1()'
In 'void fun2()'
Done

评论

0赞 Kesto2 6/11/2023
为什么它是“最好用的”而不是指向函数的指针?std::function
2赞 cse 6/11/2023
@Kesto2,模板只是一个多态函数包装器。如果你想玩转原始指针,那么使用原始函数指针是可以的。无论如何,不要提供性能改进,但我会说这是最佳实践。我能想到的一个好处是:对实例的函数调用将引发异常。因此,如果您愿意,可以在代码中捕获异常并阻止应用程序终止。std::functionstd::functionstd::functionstd::functionnullptrstd::functionstd::bad_function_call
0赞 Kesto2 6/11/2023
没关系,但我想我现在会坚持使用原始函数指针。考虑到我只是想让事情变得简单。无论如何,谢谢你的回答。
1赞 Mahendra Panpalia 6/11/2023 #3

使用可选功能:std::optional<std::function<void()>> opFunc