我想知道是否有人可以用函子帮我。我真的不明白函数是什么以及它们是如何工作的我试着用Google搜索它,但我仍然没有得到它。仿函数是如何工作的以及它们如何与模板配合使用C++模板仿函数
C++模板仿函数
回答
仿函数基本上是一个“函数对象”。这是一个单独的函数,你已经包装在一个类或结构中,并且可以传递给其他函数。
他们通过创建自己的类或结构来重载函数调用操作符(称为operator())来工作。通常,通过简单地将它构造为函数的参数来创建它的一个实例,该函数需要一个函子。
假设你有以下几点:
std::vector<int> counts;
现在,你要增加所有包含该矢量计数。你可以通过手动循环来增加它们,或者你可以使用一个仿函数。合适的仿函数,在这种情况下,应该是这样的:现在
struct IncrementFunctor
{
int operator() (int i)
{
return i + 1;
}
}
IncrementFunctor是一个仿函数这需要任意整数,并增加它。要将其应用于计数,您可以使用std :: transform函数,该函数将函子作为参数。
std::transform(
counts.begin(), // the start of the input range
counts.end(), // the end of the input range
counts.begin(), // the place where transform should place new values.
// in this case, we put it right back into the original list.
IncrementFunctor()); // an instance of your functor
语法IncrementFunctor()创建函子,然后将其直接传递到std ::变换的一个实例。当然,您可以创建一个实例作为局部变量并将其传递,但这样更方便。
现在,到模板上。 std :: transform中函子的类型是一个模板参数。这是因为std :: transform不知道(或关心!)你函子的类型。它所关心的是,它有一个合适的运营商()定义,它可以这样做
newValue = functor(oldValue);
编译器是非常聪明的模板,往往可以找出自身的模板参数是什么。在这种情况下,编译器会自动实现您传递的类型为IncrementFunctor的参数,该参数在std :: transform中定义为模板类型。它为列表中的相同,也因此编译器会自动识别出实际调用是这样的:
std::transform<std::vector<int>::iterator, // type of the input iterator
std::vector<int>::iterator, // type of the output iterator
IncrementFunctor>( // type of your functor
counts.begin(), // the start of the input range
counts.end(), // the end of the input range
counts.begin(), // the place where transform should place new values.
// in this case, we put it right back into the original list.
IncrementFunctor()); // an instance of your functor
它可以节省你不少打字。 )
函子是一些可以被调用/被叫与函数调用操作,语法上通过附加()
,任选括号内的参数列表。
这就是所有模板的需求。就模板而言,它被调用的东西是允许这种语法的任何东西 - 换句话说,可以是自由函数或覆盖operator()()
的类的实例。 (一个“free”函数只是一个不是成员的函数,也就是说,它是全局作用域的函数,或者是以前包含的名称空间范围的函数。)
外模板元编程的,我们通常不说,一个自由的功能是AA函子,并保留该名称为覆盖operator()()
一个类的实例:
struct Foo {
public:
void operator()(int i) { // do something }
void operator()(int i, char x) { // do something else }
}
在C++模板编译,所以只要在语法有道理,编译器会很乐意用一个函数或仿函数:
template<typename T> class Bar {
private int j ;
public:
Bar(int i) : j(i) {}
void doIt(T t) {
t(j) ;
}
}
Foo f;
extern void resize(int i) ; // in some header
Bar<Foo> bf(5) ;
// a Bar that is templated on Foo
Bar< void (&)(int) > br(5) ;
// a Bar that is templated on a function taking int and returning void
br.doit(&resize) ; // call resize with br.j
bf.doit(f) ; // call Foo::operator()(int) on Foo f with bf.j
- 1. C++仿函数模板
- 2. C++仿函数和函数模板
- 3. C模板仿函子。类模板vs函数模板
- 4. 模板模板C++函数
- 5. 传递一个仿函数作为C++模板参数
- 6. C++ - 通过模板仿专业成员函数模板不编译
- 7. C++:函数模板
- 8. 模仿C++静态构造函数
- 9. C++模板类和模板函数
- 10. 为函数模板C++
- 11. C++函数模板重载
- 12. C++模板函数重载
- 13. C++ variadic函数模板
- 14. C++函数模板问题
- 15. C++中的模板函数
- 16. 错误:C++模板函数
- 17. 包装C++模板函数
- 18. C++从另一个模板函数调用模板函数
- 19. 模板仿函数必须提供自己作为模板参数
- 20. Azure ARM uniqueString函数模仿
- 21. 传递仿函数在C++
- 22. Priority_queue仿函数使用C++
- 23. 作为模板函数的模板参数的模板函数
- 24. 从C调用C++模板函数#
- 25. C++模板函数特化 - 模板参数数量错误?
- 26. “模仿”C++模板的C策略是什么?
- 27. C++与指针参数模板函数
- 28. C++:数组函数模板专门化
- 29. C++模板函数与常量参数
- 30. C++中的模板函数参数14
+1,一个更好的答案,因为你确实表现出_templated_仿函数的例子。 – 2009-10-06 23:51:36
虽然这个'void(&(int))'语法怎么了?这个用法至少不是C++。它是C++/CLI吗? “ – 2009-10-06 23:57:54
”这个void(&(int))语法怎么了?“?是的,这是“一个函数的地址int和返回void”的错误。 – tpdi 2009-10-07 00:48:27