我一直在听C++中的仿函数.有人可以给我一个关于它们是什么的概述以及在什么情况下它们会有用吗?
我正在寻找涉及将C++模板函数作为参数传递的规则.
这得到了C++的支持,如下例所示:
#include <iostream>
void add1(int &v)
{
v+=1;
}
void add2(int &v)
{
v+=2;
}
template <void (*T)(int &)>
void doOperation()
{
int temp=0;
T(temp);
std::cout << "Result is " << temp << std::endl;
}
int main()
{
doOperation<add1>();
doOperation<add2>();
}
Run Code Online (Sandbox Code Playgroud)
然而,了解这种技术很困难.谷歌搜索"作为模板参数的功能"不会导致太多.令人惊讶的是,经典的C++模板完整指南也没有讨论它(至少不是我的搜索).
我的问题是这是否是有效的C++(或者只是一些广泛支持的扩展).
另外,在这种模板调用过程中,有没有办法允许具有相同签名的仿函数与显式函数互换使用?
以下就不能在上面的程序中工作,至少在视觉C++,因为语法显然是错误的.能够为仿函数切换函数是很好的,反之亦然,类似于如果要定义自定义比较操作,可以将函数指针或函子传递给std :: sort算法.
struct add3 {
void operator() (int &v) {v+=3;}
};
...
doOperation<add3>();
Run Code Online (Sandbox Code Playgroud)
指向一个或两个Web链接的指针,或C++模板书中的页面将不胜感激!
这是这个问题的后续问题:具有任何参数列表的函数的泛型函子
我有这个仿函数类(完整代码见上面的链接):
template<typename... ARGS>
class Foo
{
std::function<void(ARGS...)> m_f;
public:
Foo( std::function<void(ARGS...)> f ) : m_f(f) {}
void operator()(ARGS... args) const { m_f(args...); }
};
Run Code Online (Sandbox Code Playgroud)
在operator()中,我可以使用递归的"剥离"功能轻松访问args ...如http://www2.research.att.com/~bs/C++0xFAQ.html#variadic-templates
我的问题是:我想在构造函数中访问f的参数类型,即ARGS ....显然我无法访问值,因为到目前为止还没有,但参数类型列表以某种方式埋没在f中,不是吗?
目前我在尝试存储参数包时遇到问题,这是设计的示例代码:
template<typename Func, typename... Args>
void handleFunc(Func func, Args&&... args) {
struct nest {
Func nestFunc;
Args... nestArgs; // I DONT KNOW WHAT TO DO HERE
void setup(Func func, Args... args) {
nestFunc = func;
nestArgs = (args)...; // SO I CAN SET IT HERE
}
// Later I will forward this and run the function with its arguments
unsigned process() {
nestFunc(std::forward<Args>(nestArgs)...); // USE IT HERE
return 0;
}
};
nest* myNest;
myNest->setup(func, (args)...);
}
Run Code Online (Sandbox Code Playgroud)
这是问题所涉及的所有内容的示例,我需要存储参数以便稍后在我的nest结构中调用.此外,如果你有一个解决方案来存储它,但设置它与我的不同,也请让我知道这一点.谢谢.
我需要实现一个函数,它在实例化时接受任何(!)函数指针,分析参数类型,存储指针以及何时调用operator(),使用指针执行某些操作.最简单的情况是,用它的参数调用函数.
我尝试将函数指针转换为类似std :: function的东西,我得到错误:
error: invalid use of incomplete type ‘struct std::function<void (*)(...)>’
/usr/include/c++/4.6/functional:1572:11: error: declaration of ‘struct std::function<void(*)(...)>’
Run Code Online (Sandbox Code Playgroud)
我正在使用gcc 4.6.1,使用-std = c ++ 0x进行编译
这是一个最小的例子:
#include <functional>
using namespace std;
typedef void (*F_vararg)(...);
class Foo
{
public:
template<typename... ARGS> Foo(function<F_vararg(ARGS... args)> f);
~Foo(){}
template<typename... ARGS>void operator()(ARGS... args);
private:
F_vararg m_f;
};
template<typename... ARGS>
Foo::Foo(function<F_vararg(ARGS... args)> f)
{
m_f = f;
}
template<typename... ARGS>
void Foo::operator()(ARGS... args)
{
m_f(args...);
}
void func1(double *a1, double *a2, double *b)
{ //do something …Run Code Online (Sandbox Code Playgroud) generics variadic-functions functor variadic-templates c++11
以下模板定义
template <typename Func, typename ReturnType, typename... Arguments>
class Command
{
public:
Command(Func f) : m_func(f) { }
ReturnType operator()(Arguments... funcArgs) { return m_func(funcArgs...); }
private:
Func m_func;
};
Run Code Online (Sandbox Code Playgroud)
使用以下测试代码实例化时,使用gcc 4.7.3(错误:字段'Command :: m_func'无效声明的函数类型)给出错误消息:
void testFunction(int i, double d)
{
std::cout << "TestFunctor::operator()(" << i << ", " << d << ") called." << std::endl;
}
int main()
{
void (&fRef)(int, double) = TestFunction;
Command<void(int, double), void, int, double> testCommand(fRef);
}
Run Code Online (Sandbox Code Playgroud)
如果我将没有address-of运算符的TestFunction传递给testCommand构造函数,也会出现错误消息,但如果我传递一个显式命名的函数指针或使用address-of运算符传递参数,则会消失.我认为这段代码应该适用于Modern C++ Design的第5章.
无法存储函数引用的原因是什么,但函数指针工作正常?是否有任何变通方法可以在不失去支持的情况下编译,同时也可以将函数作为参数传递给Command的构造函数?