C ++将函数模板作为回调传递给其他函数

时间:2017-12-21 03:38:24

标签: c++ c++11 templates

我有如下功能:

template<typename... Args>
int
error_handler (const char *format, Args&... args)
{
    // deal with the information passed
}

我正在编写一个在初始化时获取此类函数指针的库,因此当发生某些事情时,库可以将其作为回调来调用。但是,我无法编写这样的API。我尝试了以下但编译器不喜欢它:

void init(template<typename... Args> int (*error_handler_cb)(const char *format, Args&... args));

这是错误:

error: expected identifier before 'template'
     void init(template<typename... Args> int (*error_logger_cb)(const char *format, Args&... args),
                      ^~~~~~~~
libapi.hpp:20:22: error: expected ',' or '...' before 'template'

有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

您不能将类型作为函数参数传递,只能传递一个值。您可以通过仅需要一个仿函数来利用init上的约束:

template<typename F>
void init(F f)
{
    // ...
}

如果您需要存储f以便稍后调用,std::function可能是一个选项:

namespace {
    std::vector<std::function<int(void)>> init_functions;
}

template<typename F>
void init(F f)
{
    init_functions.push_back(f);
}

完整的实现可能如下所示:

namespace {
    std::vector<std::function<int(void)>> init_functions;
}

template<typename... Args>
int
error_handler (const char *format, Args&&... args)
{
    do_something(format);
    do_something(args...);

    return 0;
}

template<typename F>
void init(F f)
{
    init_functions.push_back(f);
}

int main()
{
    auto f = []() {
        return error_handler("test", 4, 2);
    };
    init(f);
    return init_functions[0]();
}

请注意在error_handler中使用右值引用而不是左值引用。这允许在main函数中传递rvalues。

在rextester上查看live example