【问题标题】:C++ Sorting vector of structs with const variables alphabeticallyC++ 按字母顺序对具有 const 变量的结构向量进行排序
【发布时间】:2020-04-11 13:09:49
【问题描述】:

您好,我想知道是否可以做这样的事情? // 谢谢 ! :)

struct PET
{ 
 const char* pet;
 const int age;
};

bool Sort(const PET& first, const PET& second)
{
    return first.pet < second.pet;
}

void  Foo(const std::vector<PET> pets)
{ 
  std::sort(pets.begin(), pets.end(), Sort); /* Does not work */
  
  std::cout << pets[0].pet;
  std::cout << pets[0].age;
  
}

【问题讨论】:

  • 不,这实际上是不可能的,因为你的向量的元素是不可分配的,因为 const int 成员。请注意,另一个成员是可分配的,const 不适用于指针,而仅适用于它指向的内容。两个任务:首先,问问自己是否需要这个const 成员。其次,继续阅读你的 C++ 教程,使用像 std::sort() 这样的算法通常在高级部分,但应该在那里覆盖。此外,作为这里的新用户,请使用tour 并阅读How to Ask。尤其要避免是/否问题。
  • 啊,太糟糕了,谢谢你的回答 :) 对不起。
  • 在已有 cmets 或答案后编辑问题也确实令人困惑,以至于它与原始问题完全不同,并且这些 cmets 不再适用。

标签: c++ sorting struct constants


【解决方案1】:

我完全同意 @Ulrich Eckhardt 的观点。

您无法对向量进行排序,因为您的向量的元素不可分配。

我想,您可能对const 的用法感到困惑。

结构体变量不用const。自定义排序函数的参数一般保留为const,因为它们不应该是可修改的。这是一种确保安全编码实践的模式。

另外,如果您使用 C++,我建议使用 std::string 而不是 char*,因为 std::string 是一种更清洁、更安全的方式,因为它消除了程序员的内存管理负担。

看看工作的实现,不使用 const:

#include <string.h>
#include<iostream>
#include<vector>
#include<algorithm>

struct PET
{ 
    std::string name;
    int age;
};

bool compare(const struct PET& a, const struct PET& b){

    return (a.name.compare(b.name) <= 0) ? true : false;        
}

int main(){

    std::vector<struct PET> vec(3);

    vec[0].name = "dog";
    vec[0].age = 3;

    vec[1].name = "cat";
    vec[1].age = 1;

    vec[2].name = "bird";
    vec[2].age = 2;

    sort(vec.begin(), vec.end(), compare);

    for(int i=0;i<3;i++){

        std::cout<<vec[i].name<<" "<<vec[i].age<<std::endl;
    }
    return 0;

}

【讨论】:

    【解决方案2】:

    正如@Deepak Tatyaji Ahire 和@Ulrich Eckhardt 所说,你不能做你在代码中写的东西。

    const int 不能是变量。它是一个用于定义的常量:)

    您在代码中编写的向量不能以这种方式构建。 我不明白你想用“排序”功能做什么,我写了以下代码,也许它可以帮助:

    #include<iostream>
    #include<vector>
    
    struct PET
    {
     const char* pet;
     int age;
    
     PET(const char* c, int a) : pet(c) , age(a) {}
    
    };
    
    void  Foo(PET &p, std::vector<PET> &v)
    {
      v.push_back(p);
      /*do something here if needed*/
    
    }
    
    int main()
    {
        std::vector<PET> vect;
        PET cat("Cat", 5);
        PET dog("Dog", 10);
        PET bird("Bird", 2);
        Foo(cat, vect);
        Foo(dog, vect);
        Foo(bird, vect);
        /*this is not elegant, you could define a function that give a list of
        ({Animal, age},...) to vector and then pushes back all these elements to the vector*/
        for(int i=0; i<3; i++) std::cout<< vect[i].pet << ' ' << vect[i].age << std::endl; //std::cout << vect; if you are using an operator << overload
        /*to overload the << operator in order to able to print the vector of struct PET:
    
    std::ostream & operator << (std::ostream &os, std::vector<PET> &p)
    {
         os << "<";
        for (int i = 0; i < p.size(); i++) {
            os << p[i].pet;
            os << ", ";
            os << p[i].age;
            if (i != p.size() - 1)
                os << " - ";
        }
        os << ">\n";
        return os;
    }
    
        */
    
        return 1;
    }
    

    【讨论】:

      【解决方案3】:

      AFAIK,没有定义比较器就无法直接比较结构。

      尽管在 C++20 中,它引入了三向比较,您可能可以通过一行来声明 Default comparisons。很方便。不幸的是,还没有编译器实现这个特性。

      现在,您必须手动定义比较器

      inline bool cmp(const PET &lhs, const PET &rhs)
      {
          return std::strcmp(lhs.pet, rhs.pet)<0;
      }
      

      并将其传递给std::sort

      【讨论】:

      • 强烈同意@Mark Taylor,编辑原始问题真的很混乱。也许追加新内容会是更好的选择。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      • 1970-01-01
      • 1970-01-01
      • 2015-07-06
      • 1970-01-01
      • 2019-04-21
      • 1970-01-01
      相关资源
      最近更新 更多