【问题标题】:Use accumulate on vector of shared_ptr using function that takes base class of pointed object使用带有指向对象基类的函数在 shared_ptr 的向量上使用累积
【发布时间】:2011-12-21 11:54:54
【问题描述】:

我使用的是 VS2008(所以我有 TR1,但没有 C++11),我不使用 boost。 下面的描述是我真正问题的简化版本。

我有以下类层次结构:一个接口、一个实现它的抽象类以及从该抽象类派生的几个类:

struct IMyInterface
{
    virtual void MinMax(int& Min, int& Max)const = 0;
};

class Base : public IMyInterface // Abstract
{
// ...
};

class A: public Base
{
public:
    virtual void MinMax(int& Min, int& Max)const { // Some stuff for A}
// ...
};

class B: public Base
{
public:
    virtual void MinMax(int& Min, int& Max)const { // Some stuff for B}
// ...
};

然后我有一个shared_ptr的向量到基类:

// Somewhere in my code
typedef shared_ptr<Base> Base_sp;

vector<Base_sp> v;

我有一些代码可以做到这一点:

int Vmin = INT_MAX;
int Vmax = INT_MIN;
for(vector<Base_sp>::const_iterator it = v_sp.begin(); it != v_sp.end(); ++it)
{
    int v1, v2;
    (*it)->MinMax(v1, v2);

    Vmin = std::min(v1, Vmin);
    Vmax = std::max(v2, Vmax);
}

我在不止一个地方使用了类似的代码,所以我把它放到了一个我通过累积运行的函数中:

pair<int, int> MinMaxFinder(pair<int, int> vals, Base_sp elem)
{
    int Vmin = vals.first;
    int Vmax = vals.second;

    if (elem)
    {
        int v1, v2;
        elem->MinMax(v1, v2);

        Vmin = std::min(v1, Vmin);
        Vmax = std::max(v2, Vmax);
    }
    return make_pair(Vmin, Vmax);
}


pair<int, int> tmp = accumulate(v_sp.begin(), v_sp.end(), 
                                make_pair(INT_MAX, INT_MIN), &MinMaxFinder);
int Vmin = tmp.first;
int Vmax = tmp.second;

这很好用,但是,在我使用要替换的代码的其他地方,我不一定使用 Base_sp 派生类,而是其他 IMyInterface 派生类。所以我想像这样声明 MinMaxFinder:

pair<int, int> MinMaxFinder(pair<int, int> vals, IMyInterface* elem)

但这当然不能编译。

那么,有没有办法通过适配器或其他东西来做我想做的事?如果没有,关于如何解决这个问题的任何想法?

【问题讨论】:

  • “我不使用 boost”,你的意思是你目前没有使用它,但如果它解决了你的问题,你会使用它;还是您的意思是由于某种原因您不能或根本不想使用它?
  • 我目前不使用它,并且由于我们的“特殊”组织,开始使用它会是一个 PITA,尽管我看到它有很多有用的东西。

标签: c++ stl std


【解决方案1】:

您可以根据使用的指针类型对函数进行参数化:

template <typename MyInterfacePointer>
pair<int, int> MinMaxFinder(pair<int, int> vals, MyInterfacePointer elem)
{
    // Function body is identical to yours
    int Vmin = vals.first;
    int Vmax = vals.second;

    if (elem)
    {
        int v1, v2;
        elem->MinMax(v1, v2);

        Vmin = std::min(v1, Vmin);
        Vmax = std::max(v2, Vmax);
    }
    return make_pair(Vmin, Vmax);
}

vector<Base_sp> v_sp;   
accumulate(v_sp.begin(), v_sp.end(), 
           make_pair(INT_MAX, INT_MIN), &MinMaxFinder<Base_sp>);

vector<IMyInterface*> v_i;
accumulate(v_i.begin(), v_i.end(), 
           make_pair(INT_MAX, INT_MIN), &MinMaxFinder<IMyInterface*>);

为方便起见,这可以进一步包装在由容器类型参数化的函数中:

template <typename MyInterfacePointerContainer>
pair<int, int> FindMinMax(MyInterfacePointerContainer const & c)
{
    return accumulate(c.begin(), c.end(), make_pair(INT_MAX, INT_MIN),
        &MinMaxFinder<typename MyInterfacePointerContainer::value_type>);
}

vector<Base_sp> v_sp;
FindMinMax(v_sp);

vector<IMyInterface*> v_i;
FindMinMax(v_i);

【讨论】:

  • 谢谢!我想我必须更深入地了解模板。前几天我发布了另一个问题,解决方案基本相同。
猜你喜欢
  • 2012-08-30
  • 1970-01-01
  • 2018-09-17
  • 2013-02-03
  • 1970-01-01
  • 2022-11-13
  • 2019-04-13
  • 2021-11-30
  • 1970-01-01
相关资源
最近更新 更多