我正在尝试使用模板varargs传递lambda作为参数
I am trying to pass a lambda as argument with template varargs
我仍在为一些C++语法而挣扎
这一次,我想用lambda添加额外的参数。但是为了使代码通用,我希望能够接受任何函数及其参数:
#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);
}
这将生成:
> 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 ...)
我尝试明确指定模板类型:
Nisse<int> nisse<int,double>([](int a,double d){return 5;},12,12.0);
但这(令我惊讶)是一个语法错误:
> 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
不能从lambda推断std::function
模板参数。接受任意可调用文件的常用方法是通过通用引用:
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的结果。
std::enable_if<std::is_convertible<
decltype(std::declval<F>()(std::declval<Args>()...)), R>::value>::type
正如@Yakk在下面的评论中所描述的,上面的表达式检查F是否是一个结果为R的函数类型。如果它有效,那么一切都很好。如果失败,则会生成编译时错误(注意:这使用SFINAE)。
对于方法,SFINAE被插入到返回类型中,但对于构造函数,这不是一个选项;从历史上看,添加了一个额外的默认构造函数参数,但添加一个默认模板参数更优雅,因为它根本不会更改构造函数签名。匿名模板参数的SFINAE在可变模板参数之后特别有吸引力,因为用户无法(意外地?)覆盖默认值。
相关文章:
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 将对象数组的引用传递给函数
- Pybind11:将元组列表从Python传递到C++
- std::向量与传递值的动态数组
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 使用指向成员的指针将成员函数作为参数传递
- Ctypes wstring通过引用传递
- C++数组传递给大小为的函数
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- C++/传递值导致#DEN
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何将参数传递给正在使用模板的类
- 将重载的成员函数传递给函数模板
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 如何将函数集合传递给客户端类,以便将它们当作客户端类本身的成员使用
- 通过JNI传递数据数组的最快方法是什么
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 如何在 GCC 中将"non trivially copyable objects"传递到 varargs 函数中
- 我正在尝试使用模板varargs传递lambda作为参数