关于用用户定义的方法扩展C ++ STL容器的更好方法的建议 [英] Advice on a better way to extend C++ STL container with user-defined methods

查看:122
本文介绍了关于用用户定义的方法扩展C ++ STL容器的更好方法的建议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从C ++ STL容器继承,并添加我自己的方法。理由是,对于客户,它将看起来作为一个常规列表,但具有应用程序特定的方法,他们可以很容易地被称为。



这工作正常,但我已经阅读了许多关于不继承从STL的帖子。有人可以提供具体的建议,我如何写下面的代码更好的方式?

  class Item 
{
int a;
int b;
int c;

int SpecialB()
{
return a * b + c;
}
};

class ItemList:public std :: vector< Item>
{
int MaxA()
{
if(this-> empty())
throw;

int maxA =(* this)[0] .a;

for(int idx = 1; idx< this-> size(); idx ++)
{
if((* this)[idx] maxA)
{
maxA =(* this)[idx] .a;
}
}
return maxA;
}

int SpecialB()
{
if(this-> empty())
throw;

int specialB =(* this)[0] .SpecialB();

for(int idx = 1; idx {
if((* this)[idx] .SpecialB < specialB)
{
specialB - =(* this)[idx] .c;
}
}
return specialB;
}

int AvgC()
{
if(this-> empty())
throw;

int cSum = 0;
for(int idx = 0; idx {
cSum + =(* this)[idx] .c;
}

return cSum / this-> size(); // average
}
};

EDIT :感谢您提供一系列深思熟虑的答案。

解决方案

为什么你需要以这种方式扩展向量?



与您的函子使用标准< algorithm>



std :: min_element std :: max_element

  int max_a = std :: max_element 

v.begin(),
v.end(),
boost :: bind(
std :: less< int>(),
bind(& Item :: a,_1),
bind(& Item :: a,_2)

) - &

std :: accumulate - 用于计算费用

  const double avg_c = std :: accumulate(v.begin(),v.end(),double(0),boost :: bind(Item :: c,_1))/ v.size (); // ofcourse check size before divide 

您的ItemList :: SpecialB()可以重写为:

  int accumulate_func(int start_from,int result,const Item& item)
{
if(item.SpecialB ()< start_from)
{
result - = item.SpecialB();
}
return result;
}

if(v.empty())
{
throw someoneghing(empty vector);
}
const int result = std :: accumulate(v.begin(),v.end(),v.front(),boost :: bind(& accumulate_func,v.front ,_1,_2));

BTW:如果你不需要访问成员,你不需要继承。 p>

I inherited from C++ STL container and add my own methods to it. The rationale was such that to the clients, it will look act a regular list, yet has application-specific methods they can readily be called.

This works fine, but I have read numerous posts about not inheriting from STL. Can someone provide a concrete advice of how I might write the code below in a better way?

class Item
{
  int a;
  int b;
  int c;

  int SpecialB()
  {
    return a * b + c;
  }
};

class ItemList : public std::vector<Item>
{
  int MaxA()
  {
    if( this->empty() )
      throw;

    int maxA = (*this)[0].a;

    for( int idx = 1; idx < this->size(); idx++ )
    {
      if( (*this)[idx].a > maxA )
      {
        maxA = (*this)[idx].a;
      }
    }
    return maxA;
  }

  int SpecialB()
  {
    if( this->empty() )
      throw;

    int specialB = (*this)[0].SpecialB();

    for( int idx = 1; idx < this->size(); idx++ )
    {
      if( (*this)[idx].SpecialB() < specialB )
      {
        specialB -= (*this)[idx].c;
      }
    }
    return specialB;
  }

  int AvgC()
  {
    if( this->empty() )
      throw;

    int cSum = 0;
    for( int idx = 0; idx < this->size(); idx++ )
    {
      cSum += (*this)[idx].c;
    }

    return cSum / this->size(); // average
  }
};

EDIT: Thanks for a bunch of thoughtful answers. I will create helper functions instead and from now on will never inherit from STL containers.

解决方案

why you need extend vector in this way?

use standard <algorithm> with your functors.
e.g.

std::min_element, std::max_element

int max_a = std::max_element
        ( 
            v.begin(), 
            v.end(), 
            boost::bind( 
                std::less< int >(),
                bind( &Item::a, _1 ), 
                bind( &Item::a, _2 ) 
            )
        )->a;

std::accumulate - for calculate avarage

const double avg_c = std::accumulate( v.begin(), v.end(), double( 0 ), boost::bind( Item::c, _1 ) ) / v.size(); // ofcourse check size before divide  

your ItemList::SpecialB() could be rewrited as:

int accumulate_func( int start_from, int result, const Item& item )
{
   if ( item.SpecialB() < start_from )
   {
       result -= item.SpecialB();
   }
   return result;
}

if ( v.empty() )
{
    throw sometghing( "empty vector" );
}
const int result = std::accumulate( v.begin(), v.end(), v.front(), boost::bind( &accumulate_func, v.front(), _1, _2 ) );

BTW: if you don't need access to members, you don't need inheritance.

这篇关于关于用用户定义的方法扩展C ++ STL容器的更好方法的建议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆