std::具有多个排序选项的集合 我想对C++的STD::set容器有< >强>多个排序选项。 我尝试创建一个引用私有类成员(sortingMethod)的自定义比较器,以决定如何排序: class StudentBook{ int sortingMethod; //0-BY_ID, 1-BY_AGE, 2-BY_GPA, etc... struct studentComparator { bool operator()(Student* a, Student* b) { switch (sortingMethod) { case 1: return a->getId() >= b->getId(); break; case 2: return a->getAge() >= b->getAge(); break; case 3: return a->getGPA() >= b->getGPA(); break; default: return true; break; } }; std::set<Student*, studentComparator> students; 班级学生手册{ int-sortingMethod;//0-BY\u ID,1-BY\u AGE,2-BY\u GPA,等等。。。 结构学生比较器{ 布尔运算符()(学生*a,学生*b) { 开关(排序方法){ 案例1: 返回a->getId()>=b->getId(); 打破 案例2: 返回a->getAge()>=b->getAge(); 打破 案例3: 返回a->getGPA()>=b->getGPA(); 打破 违约: 返回true; 打破 } }; std::set学生;

std::具有多个排序选项的集合 我想对C++的STD::set容器有< >强>多个排序选项。 我尝试创建一个引用私有类成员(sortingMethod)的自定义比较器,以决定如何排序: class StudentBook{ int sortingMethod; //0-BY_ID, 1-BY_AGE, 2-BY_GPA, etc... struct studentComparator { bool operator()(Student* a, Student* b) { switch (sortingMethod) { case 1: return a->getId() >= b->getId(); break; case 2: return a->getAge() >= b->getAge(); break; case 3: return a->getGPA() >= b->getGPA(); break; default: return true; break; } }; std::set<Student*, studentComparator> students; 班级学生手册{ int-sortingMethod;//0-BY\u ID,1-BY\u AGE,2-BY\u GPA,等等。。。 结构学生比较器{ 布尔运算符()(学生*a,学生*b) { 开关(排序方法){ 案例1: 返回a->getId()>=b->getId(); 打破 案例2: 返回a->getAge()>=b->getAge(); 打破 案例3: 返回a->getGPA()>=b->getGPA(); 打破 违约: 返回true; 打破 } }; std::set学生;,c++,C++,} 此代码未编译。错误: “从此位置”,“非静态数据成员'StudentBook::sortingMethod'的使用无效” 我想使用集合,因为它的“无重复项”属性。 有正确的方法吗,或者我应该切换到另一个STL容器吗?代码中的问题是,您试图在studentComparator类中引用sortingMethod。您不能这样做,因为studentComparator是一个独立的类,无法访问封闭类的成员变量除非你把外部实例的指针/引用传递给内部实例(我认为这是C++和java之间的(许多)差异之一)

}

此代码未编译。错误:

“从此位置”,“非静态数据成员'StudentBook::sortingMethod'的使用无效”

我想使用集合,因为它的“无重复项”属性。
有正确的方法吗,或者我应该切换到另一个STL容器吗?

代码中的问题是,您试图在
studentComparator
类中引用
sortingMethod
。您不能这样做,因为
studentComparator
是一个独立的类,无法访问封闭类的成员变量除非你把外部实例的指针/引用传递给内部实例(我认为这是C++和java之间的(许多)差异之一)。 其思想是构造一个comparator函子,该函子以您想要排序的方式作为构造函数参数。换句话说,您的comparator函子具有state。在构造
std::set
时,您需要显式地。 下面是一个简单的示例,说明了如何使用2状态布尔比较器执行此操作,您可以进一步对其进行概括:

#include <iostream>
#include <set>
#include <string>

struct Foo
{
    int age_;
    std::string name_;
    friend std::ostream& operator<<(std::ostream& os, const Foo& rhs)
    {
        return os << rhs.age_ << " " << rhs.name_;
    }
    struct Compare // custom comparator
    {
        bool by_name_; // compare by age
        Compare(bool by_name = false): by_name_(by_name) {}
        bool operator()(const Foo& lhs, const Foo& rhs)
        {
            return by_name_ ? (lhs.name_ < rhs.name_) : (lhs.age_ < rhs.age_);
        }
    };
};

int main()
{
    Foo x{1, "Silver"}, y{2, "John"}, z{3, "Long"};

    std::set<Foo, Foo::Compare> by_name(Foo::Compare{true}); // sort by name
    by_name.insert(x);
    by_name.insert(y);
    by_name.insert(z);

    std::set<Foo, Foo::Compare> by_age(Foo::Compare{false}); // sort by age
    by_age.insert(x);
    by_age.insert(y);
    by_age.insert(z);

    std::cout << "By name:" << std::endl;
    for (auto && elem : by_name)
        std::cout << elem << std::endl;
    std::cout << "By age:" << std::endl;
    for (auto && elem : by_age)
        std::cout << elem << std::endl;
}
#包括
#包括
#包括
结构Foo
{
国际年龄;
std::字符串名称;

friend std::ostream&运算符切换排序模式将需要对
std::set
进行完全重构。我怀疑是否有办法做到这一点。您可以在实际结构周围(针对每个比较器)设置一个包装器它包含对数据实际实例的引用,并对给定用例具有适当的比较运算符。a)类内的结构独立于它。您不能在
studentComparator
中访问
sortingMethod
,如果
sortingMethod
StudentBook
的一部分,则需要
Studen>的某个对象tBook
针对此危险:填充集合后更改排序方法可能会导致未定义的行为。@Yakk我不明白…在构造时,
std::set
正在复制其中的函子。我没有使用
static
标志。你能详细说明一下吗?你在考虑
std::sort
?不是针对你的代码,但是在技术方面。在OP的例子中,控制int是外部存储的(您的技术可以通过存储
int*
)进行调整),这种方式是疯狂的。您的回答解决了一个技术问题,但没有警告悬崖附近。