首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我尝试将lambda作为参数传递给模板varargs

我尝试将lambda作为参数传递给模板varargs
EN

Stack Overflow用户
提问于 2013-02-15 01:47:07
回答 1查看 708关注 0票数 1

我仍然在努力学习一些C++语法。

这一次,我想用lambda添加额外的参数。但是为了使代码泛型,我希望能够接受任何函数及其参数:

代码语言:javascript
复制
#include <functional>
#include <exception> 

template<typename R>
class Nisse
{
    private:
        Nisse(Nisse const&)             = delete;
        Nisse(Nisse&&)                  = delete;
        Nisse& operator=(Nisse const&)  = delete;
        Nisse& operator=(Nisse&&)       = delete;
    public:
        //Nisse(std::function<R()> const& func) {}  // disable for testing

        template<typename... Args>
        Nisse(std::function<R(Args...)> const& func, Args... a) {}
};

int main()
{
    // I  was hoping this would deduce the template arguments.
    Nisse<int>   nisse([](int a,double d){return 5;},12,12.0);
}

这将生成:

代码语言:javascript
复制
> g++ -std=c++0x Test.cpp 
Test.cpp:21:61: error: no matching function for call to ‘Nisse<int>::Nisse(main()::<lambda(int, double)>, int, double)’
Test.cpp:21:61: note: candidate is:
Test.cpp:16:9: note: template<class ... Args> Nisse::Nisse(const std::function<R(Args ...)>&, Args ...)

我尝试显式指定模板类型:

代码语言:javascript
复制
    Nisse<int>   nisse<int,double>([](int a,double d){return 5;},12,12.0);

但这(令我惊讶的)是一个语法错误:

代码语言:javascript
复制
> g++ -std=c++0x Test.cpp 
Test.cpp: In function ‘int main()’:
Test.cpp:21:23: error: expected initializer before ‘<’ token
Test.cpp:21:65: error: expected primary-expression before ‘,’ token
Test.cpp:21:73: error: expected ‘;’ before ‘)’ token
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-15 02:00:57

你不能从一个lambda中推断出std::function模板参数。接受任意可调用的通常方式是通过通用引用:

代码语言:javascript
复制
    template<typename F, typename... Args,
      typename = typename std::enable_if<std::is_convertible<
        decltype(std::declval<F>()(std::declval<Args>()...)), R>::value>::type>
    Nisse(F &&f, Args... a): Nisse(std::function<R()>(std::bind(f, a...))) {}

最后一个(匿名的,默认的)模板参数在这里用于验证第一个模板参数是否为类似函数,并返回R类型的结果。

代码语言:javascript
复制
std::enable_if<std::is_convertible<
    decltype(std::declval<F>()(std::declval<Args>()...)), R>::value>::type

正如@Yakk在下面的注释中所描述的,上面的表达式检查F是否是一个结果为R的函数类型。如果它可以工作,那么一切都很好。如果失败,则会生成一个编译时错误(注意:这里使用SFINAE)。

对于方法,SFINAE被插入到返回类型中,但对于构造函数,这不是一个选项;以前添加了额外的默认构造函数参数,但添加默认模板参数更优雅,因为它根本不会更改构造函数签名。匿名模板参数的SFINAE在可变模板参数之后特别有吸引力,因为用户没有办法(意外地?)覆盖默认值。

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

https://stackoverflow.com/questions/14880934

复制
相关文章

相似问题

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