【问题标题】:How do I define a sort predicate for a templated container class in C++如何在 C++ 中为模板化容器类定义排序谓词
【发布时间】:2014-06-11 23:14:42
【问题描述】:

我的 C++ 最近有点生疏了。你们中的一位大师可以帮我为容器类定义一个 SORT 谓词,它带有一个模板参数,它本身就是另一个类。

template <class Element>
class OrderedSequence
// Maintains a sequence of elements in
// ascending order (by "<"), allowing them to be retrieved
// in that order.
{


 public:
 // Constructors
 OrderedSequence();

 OrderedSequence(const OrderedSequence<Element>&);

 // Destructor
 ~OrderedSequence(); // destructor

 OrderedSequence<Element>& operator= (const OrderedSequence<Element>& ws);

 // Get an element from a given location
 const Element& get (int k) const;



// Add an element and return the location where it
// was placed.
int add (const Element& w);

bool empty() const      {return data.empty();}
unsigned size() const   {return data.size();}


// Search for an element, returning the position where found
// Return -1 if not found.
int find (const Element&) const;


void print () const;

bool operator== (const OrderedSequence<Element>&) const;
bool operator< (const OrderedSequence<Element>&) const;

private:

std::vector<Element> data;

};

所以,这个类接收一个模板参数,它是一个带有 std::string 成员变量的 STRUCT。

我想定义一个简单的排序谓词,以便我可以调用: std::sort(data.begin(), data.end(), sort_xx) 执行后: 数据.push_back() 在上面类的 add() 成员函数中。

我该怎么做?我没有使用 C++ 11 - 只是普通的旧 C++。

模板参数 Element.. 被翻译成:

struct AuthorInfo 
{
string name;
Author* author;

AuthorInfo (string aname)
   : name(aname), author (0)
 {}

bool operator< (const AuthorInfo&) const;
bool operator== (const AuthorInfo&) const;
};

bool AuthorInfo::operator< (const AuthorInfo& a) const
{
   return name < a.name;
}

bool AuthorInfo::operator== (const AuthorInfo& a) const
{
  return name == a.name;
}

【问题讨论】:

  • 您究竟想如何订购Element 对象? (另外,普通的旧 C++ C++11。你可能的意思是你仍然受限于 C++03。)
  • 是的,先生,我的朋友(这是他的代码)只使用 C++03。我不再编程,所以有点失去联系,先生。我希望按升序排列元素。并且 element 是带有 std::string 的 STRUCT 。对于经常用 C++ 编程的人来说应该不会太难。欢呼与和平。
  • 您应该使用股票std::less&lt;&gt; 作为您的谓词,但老实说,该谓词不应该用于sort,因为您一开始就不应该使用它。它应该用于 upper_bound ,您应该首先使用它来定位正确的插入点,而不是使用您最后拍打的每个项目来重新定位整个序列。
  • @WhozCraig。我理解你关于排序逻辑的观点。感谢那。我只是自己查看了这段代码。很快就会看到它。感谢您的观察。
  • 总之。在这个项目中,OOD 似乎很好——足以让我根本不需要谓词——至少从基本的功能(需求)角度来看。排序函数不需要谓词,因为 AuthorInfo 的重载

标签: c++ sorting templates functor predicates


【解决方案1】:

如果需要自定义谓词,可以使用std::find_if

要定义谓词 ala C++03:

// For find()
struct MyPredicate
{
public:
  explicit MyPredicate(const std::string name) name(name) { }

  inline bool operator()(const Element & e) const { return e.name == name; }

private:
  std::string name;
};

// Assuming you want to lookup in your vector<> member named "data"
std::find_if(data.begin(), data.end(), MyPredicate("Luke S."));

// To sort it, its exactly the same but with a Sort comparer as the predicate:
struct MySortComparator
{
 bool operator() (const Element& a, const Element& b) const
 {
    return a.name < b.name;
 }
};

std::sort(data.begin(), data.end(), MySortComparator());

// Or you can style sort Author without predicates if you define `operator<` in the `Element` class :
std::sort(data.begin(), data.end())

如果你可以使用 C++11,你可以简单地使用 lambda:

std::find_if(data.begin(), data.end(), [](const Element & e) -> bool { return e.name == "Luke S."; });

编辑:

现在你显示Element 我看到你已经在Author 中重载了operator==,所以你也可以这样做:

int find (const Element& e) const
{
  std::vector<Element>::iterator iter = std::find(data.begin(), data.end(), e);
  return std::distance(data.begin(), iter);
}

【讨论】:

  • 我已经发布了上面的元素参数翻译。干杯。
  • 所以只需将我的 GetString() 替换为 name ?已编辑
  • 另外,我实际上正在寻找使用简单的排序谓词对向量(称为)数据进行排序。谢谢。
  • 是的,我知道 GetString() 函数及其用法。我的问题是这个 std::sort 在 OrderedSequence 的成员函数中被调用,并且我试图在自定义容器类的上下文中正确获取 C++ 谓词的语义——这就是这个类的本质。
  • MyPredicate 不是排序顺序。 (不过,两个参数 sort 会起作用。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
  • 1970-01-01
  • 2013-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多