c – 无法结合GP和OOP概念

我有一个带有模板化成员函数的类:

class Person
{
  template <typename TItem>
  void DoSomething(TItem item)
  {
    item.Action();
  } 
};

这允许我传递具有Action成员函数的任何项目,该人员将使用该项目执行该操作.所以我能做到:

Person person;
BaseballBat bat;
person.DoSomething(bat);

这种结构允许我用任何类型的对象调用函数.但是,如果我想存储任何类型的对象,我必须模板化该类:

template <TItem>
class Person
{
public:
  void DoSomething()
  {
    this->Item.Action();
  }

  void SetItem(TItem item)
  {
    this->Item = item;
  }
private:
  TItem Item;
};

Person<BaseballBat> person;
BaseballBat bat;
person.SetItem(&bat);
person.DoSomething();

这很烦人,因为我必须重新实例化Person类来改变对象的类型.

或者,我可以从父类派生项目:

class Person
{
public:
  void DoSomething()
  {
    this->Item.Action();
  }

  void SetItem(TItem* item)
  {
    this->Item = item;
  }

private:
  ParentItem* Item;
};

class ParentItem{};

class BaseballBat : public ParentItem
{}

Person person;
BaseballBat bat;
person.SetItem(&bat);
person.DoSomething();

这很烦人,因为我必须维护所有项目的继承结构(看起来非常“非GP”).

当我有多层“包含对象的对象”时,问题确实来了 – 也就是说,我必须将函数模板参数从一个非常“顶级”调用“传递”到包含的类:

class BaseballBat
{
  void DoAction();
};

class Child
{
  template <typename TItem>
  void DoAction(TItem item)
  {
    item.DoAction();
  }
};

class Person
{
  Child child;

  // This is annoying to have to pass the item to the person,who then has to pass it to the child. I'd rather "give" the child an Item,then just be able to call child.DoAction(),where the Person doesn't know anything about the item.
  template <typename TItem>
  void PlayWithChild(TItem item)
  {
    child.DoAction(item);
  }
}

任何人都可以评论如何正确地混合这两个功能模板的想法和存储对象作为成员数据? (以上只是试图证明的俗气的例子 – 如果它们没有意义,或者你有更好的例子,我全都耳朵:)).

———编辑———
也许更好的例子是简化我的实际情况.
我有一个具有成员函数的类Matcher:

template<typename TDistanceFunctor,typename TPropagationFunctor>
void Matcher::Compute(TDistanceFunctor distanceFunctor,TPropagationFunctor propagationFunctor);

然后我有另一个使用Matcher的类ImageAlgorithm:

template<typename TMatcher>
void ImageAlgorithm::Compute(TMatcher matcher)
{
  matcher.Compute(...); // How do I get the DistanceFunctor and the PropagationFunctor here?
}

我想称之为:

Matcher myMatcher;
.... Setup matcher (how?) ...
ImageAlgorithm algorithm;
algorithm.Compute(myMatcher);

我不知道如何通过ImageAlgorithm对象“传递”DistanceFunctor和PropagationFunctor,因此它可以到达ImageAlgorithm :: Compute调用内的Matcher对象.当然我可以在TDistanceFunctor上模拟Matcher并将TDistanceFunctor存储为成员变量,但后来我无法将匹配器使用的距离函数更改为不同类型的距离函子.

解决方法

您可以尝试使用 boost::any来保存类型变体成员.

从概述:

The boost::any class (…) supports copying of any value type and safe checked extraction of that value strictly against its type.

编辑

你是对的,用boost来调用存储的仿函数会有问题.所以我建议另一种方案:
使用std :: function(或boost :: function)来包装你的仿函数.这样,匹配器可以保存相关语法的函数对象(例如,没有参数),并且不需要在仿函数类型上进行模板化.

函数对象已经为您完成了OO(至少在某种意义上)和GP之间的组合.

相关文章

首先GDB是类unix系统下一个优秀的调试工具, 当然作为debug代...
1. C语言定义1个数组的时候, 必须同时指定它的长度.例如:int...
C++的auto关键字在C+⬑新标准出来之前基本...
const关键字是用于定义一个不该被改变的对象,它的作用是告诉...
文章浏览阅读315次。之前用C语言编过链表,这几天突然想用C+...
文章浏览阅读219次。碰到问题就要记录下来,防止遗忘吧。文章...