Functor类在构造函数中工作

时间:2009-03-07 16:10:09

标签: c++ templates functor strategy-pattern

我正在使用C ++模板传递策略仿函数来改变我的函数的行为。它工作正常。我传递的仿函数是一个没有存储空间的无状态类,它只是以经典的仿函数方式重载了()运算符。

template <typename Operation> int foo(int a) 
{
int b=Operation()(a);
/* use b here, etc */
}

我经常这样做,而且效果很好,而且我经常会制作带有6或7个模板仿函数的模板!

然而,我担心代码优雅和效率。仿函数是无状态的所以我假设Operation()构造函数是免费的,仿函数的评估和内联函数一样有效,但是像所有的C ++程序员一样,我总是有一些唠叨的怀疑。

我的第二个问题是我是否可以使用替代仿函数方法..一个不覆盖()运算符的方法,但是在构造函数中将所有内容都作为副作用! 类似的东西:

struct Operation {
  Operation(int a, int &b) { b=a*a; }
};
template <typename Operation> int foo(int a) 
 {
   int b;
   Operation(a,b);
    /* use b here, etc */
 }

我从未见过有人使用构造函数作为仿函数的“工作”,但它似乎应该有效。有什么优势吗?任何劣势?我喜欢删除奇怪的加倍括号“Operator()(a)”,但这可能只是美学。

5 个答案:

答案 0 :(得分:2)

  

有什么不利之处吗?

  • Ctors不会返回任何有用的值 - 不能在链式调用中使用(例如foo(bar())。
  • 他们可以扔。
  • 设计观点 - ctors是对象创建函数,并不是真正意义上的主力。

答案 1 :(得分:1)

  1. 编译器实际内联操作的空构造函数(在类似情况下至少是gcc,除非你关闭了优化)
  2. 在构造函数中执行所有操作的缺点是您不能以这种方式创建具有某种内部状态的仿函数 - 例如。用于计算满足谓词的元素数的仿函数。此外,使用真实对象的方法作为函子允许您存储它的实例以供以后执行,这是构造函数方法无法做到的。

答案 2 :(得分:1)

从性能pov开始,使用VC和GCC对代码进行了全面优化。但是,更好的策略通常是将仿函数作为参数,这样您就可以获得更多的灵活性和相同的性能特征。

答案 3 :(得分:0)

我建议定义使用STL容器的仿函数,即它们应该实现operator()。 (遵循您使用的语言的API总是一个好主意。)

允许你的算法非常通用(传递函数,函子,stl-bind,boost :: function,boost :: bind,boost :: lambda,...)这是人们通常想要的。

这样,您不需要将仿函数类型指定为模板参数,只需构造一个实例并将其传递给:

my_algorithm(foo, bar, MyOperation())

答案 4 :(得分:0)

在另一个类中实现构造函数似乎没有任何意义 你所做的就是打破封装并设置你的课程以便滥用。

构造函数应该将对象初始化为类所定义的良好状态。您允许另一个对象初始化您的类。您有什么保证这个模板类知道如何正确初始化您的类?您的类的用户可以提供任何可能以非预期方式混淆对象内部状态的对象。

该类应该是自包含的,并将自身初始化为良好状态。你似乎正在做的是玩模板只是为了看看他们能做些什么。