使用 Boost 插入期间基于 class 成员参数的排序集

Sorting set based on class member parameter during insertion with Boost

我刚刚开始学习 Boost 的基础知识,目前正在处理以下练习:

Create a program with multiple objects of a type animal with the member variables name, legs and has_tail. Store the objects in a container from Boost.PointerContainer. Sort the container in ascending order based on legs and write all elements to standard output.

问题源于我无法在插入完成后对容器进行排序,我可能应该尝试仅使用 PointerContainer 库。

以下是我根据教程提供的示例之一编写的代码

class Animal{
    private:
        std::string name;
        int legs;
        bool hasTail;
    public:
        Animal() = delete;
        Animal(char* aName, int nLegs = 0, bool sTail = false) : name(aName), legs(nLegs), hasTail(sTail) {};
        inline int getLegs(){ return legs; };
        friend std::ostream& operator<<(std::ostream& os, const Animal& animal);
};

std::ostream& operator<<(std::ostream& os, const Animal& animal)
{
  os << "Name: " << animal.name << " || Legs: " << animal.legs << " || Has a tail? " << animal.hasTail << std::endl;
  return os;
}

int main()
{
  Animal cat("Cat", 4, true), spider("Common Spider", 8, false), slug("Slug");
  std::set<std::unique_ptr<Animal>, boost::indirect_fun<std::less<int>>> v;
  v.insert(std::unique_ptr<Animal>(&cat));
  v.insert(std::unique_ptr<Animal>(&spider));
  v.insert(std::unique_ptr<Animal>(&slug));

  //print result

}

当然我知道这不构建的原因是因为我试图将 indirect_fun 与 int 参数一起使用,但我正在将 Animal 类型的对象传递给集合,它只是让您了解我 "allowed" 用于练习的工具以及我的总体想法。

您需要 'tell' std::less 如何比较您的 Animal 对象:

bool operator<(const Animal& a, const Animal& b) { return a.getLegs() < b.getLegs(); }

(并使 getLegs() const 生效)。 更新示例:

#include <boost/ptr_container/ptr_set.hpp>
#include <boost/ptr_container/indirect_fun.hpp>
#include <set>
#include <memory>
#include <functional>
#include <iostream>


class Animal{
    private:
        std::string name;
        int legs;
        bool hasTail;
    public:
        Animal() = delete;
        Animal(std::string aName, int nLegs = 0, bool sTail = false) : name(aName), legs(nLegs), hasTail(sTail) {};
        inline int getLegs() const{ return legs; };
        friend std::ostream& operator<<(std::ostream& os, const Animal& animal);
};

bool operator<(const Animal& a, const Animal& b) { return a.getLegs() < b.getLegs(); }

std::ostream& operator<<(std::ostream& os, const Animal& animal)
{
  os << "Name: " << animal.name << " || Legs: " << animal.legs << " || Has a tail? " << animal.hasTail << std::endl;
  return os;
}

int main()
{
  std::set<std::unique_ptr<Animal>, boost::indirect_fun<std::less<Animal>>> v;
  v.insert(std::unique_ptr<Animal>(new Animal("Cat", 4, true)));
  v.insert(std::unique_ptr<Animal>(new Animal("Common Spider", 8, false)));
  v.insert(std::unique_ptr<Animal>(new Animal("Slug")));

  for(const auto& animal: v)
  {
    std::cout << *animal << std::endl;   
  }
}
$ g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
Name: Slug || Legs: 0 || Has a tail? 0

Name: Cat || Legs: 4 || Has a tail? 1

Name: Common Spider || Legs: 8 || Has a tail? 0

http://coliru.stacked-crooked.com/a/8d8f635dc357404f