首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >C++11可变std::function参数

C++11可变std::function参数
EN

Stack Overflow用户
提问于 2012-02-12 01:16:20
回答 2查看 22.8K关注 0票数 25

名为test的函数以std::function<>作为其参数。

代码语言:javascript
复制
template<typename R, typename ...A>
void test(std::function<R(A...)> f)
{
    // ...
}

但是,如果我执行以下操作:

代码语言:javascript
复制
void foo(int n) { /* ... */ }

// ...

test(foo);

编译器(gcc 4.6.1)说no matching function for call to test(void (&)(int))

如何修改test()函数,以使最后一行test(foo)能够正常编译和工作?在test()函数中,我需要类型为std::function<>f

我的意思是,有没有什么模板技巧可以让编译器确定函数的签名(例如foo),并自动将其转换为std::function<void(int)>

编辑

我也想让lambdas(有状态的和无状态的)都能用。

EN

回答 2

Stack Overflow用户

发布于 2012-02-12 01:19:23

看起来您想要使用重载

代码语言:javascript
复制
template<typename R, typename ...A>
void test(R f(A...))
{
    test(std::function<R(A...)>(f));
}

这个简单的实现将接受您将尝试传递的大部分函数。外来函数将被拒绝(如void(int...))。更多的工作会给你更多的通用性。

票数 14
EN

Stack Overflow用户

发布于 2014-05-31 20:51:15

这是一个旧的主题,我似乎找不到太多关于相同主题的内容,所以我想我应该继续添加一个注释。

在GCC 4.8.2上编译的作品如下:

代码语言:javascript
复制
template<typename R, typename... A>
R test(const std::function<R(A...)>& func)
{
    // ...
}

然而,你不能仅仅通过传递你的指针,lambdas等来调用它。然而,下面两个例子都适用于它:

代码语言:javascript
复制
test(std::function<void(int, float, std::string)>(
        [](int i, float f, std::string s)
        {
            std::cout << i << " " << f << " " << s << std::endl;
        }));

另外:

代码语言:javascript
复制
void test2(int i, float f, std::string s)
{
    std::cout << i << " " << f << " " << s << std::endl;
}

// In a function somewhere:
test(std::function<void(int, float, std::string)>(&test2));

这些方法的缺点应该非常明显:您必须显式地为它们声明std::函数,这看起来可能有点丑陋。

这就是说,我把它和一个元组放在一起,这个元组被扩展来调用传入的函数,它可以工作,只需要显式地说明你调用测试函数做了什么。

包含元组的示例代码,如果您想使用它的话:http://ideone.com/33mqZA

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9242234

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档