C++ 如何告诉std::设置为';刷新';是点菜吗?

C++ 如何告诉std::设置为';刷新';是点菜吗?,c++,stl,C++,Stl,如果集合中某个元素的值发生变化,则排序可能不再正确。如本小程序所示: #include <algorithm> #include <iostream> #include <set> #include <string> struct Comp { bool operator()(const std::string * lhs, const std::string * rhs) { return *lhs < *

如果集合中某个元素的值发生变化,则排序可能不再正确。如本小程序所示:

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

struct Comp
{
    bool operator()(const std::string * lhs, const std::string * rhs)
    {
        return *lhs < *rhs;
    }
};

int main()
{
    typedef std::set<std::string*, Comp> MySet;
    MySet mySet;

    std::string * a = new std::string("a");
    mySet.insert(a);

    std::string * c = new std::string("c");
    mySet.insert(c);

    std::string * b = new std::string("b");
    mySet.insert(b);

    for (MySet::iterator it = mySet.begin(); it != mySet.end(); ++it)
    {
        std::cout << *(*it) << std::endl;
    }

    // Ouput has correct order:
    // a
    // b
    // c


    *b = "z";
    std::cout << std::endl;

    std::string * d = new std::string("d");
    mySet.insert(d);    

    for (MySet::iterator it = mySet.begin(); it != mySet.end(); ++it)
    {
        std::cout << *(*it) << std::endl;
    }

    // Output no longer ordered correctly:
    // a
    // d
    // z
    // c

    return 0;
}
#包括
#包括
#包括
#包括
结构组件
{
布尔运算符()(常数std::string*lhs,常数std::string*rhs)
{
返回*左侧<*右侧;
}
};
int main()
{
typedef std::set MySet;
MySet-MySet;
std::string*a=新的std::string(“a”);
mySet.插入(a);
std::string*c=新的std::string(“c”);
mySet.插入(c);
std::string*b=新的std::string(“b”);
mySet.插入(b);
for(MySet::iterator it=MySet.begin();it!=MySet.end();++it)
{
std::cout这里的主题非常相似(虽然不是完全重复,因为您使用自定义比较存储指向可变对象的指针):


基本上,不要做你想做的事。相反,当你想修改一个
集合
持有指针的对象时,首先移除指针,然后修改对象,然后重新插入指针。

简单地说,你不能。如果你将一个项目放入集合,你不应该以改变其顺序的方式更改该项目。如果你需要d要以这种方式更改项目,则需要将其从集合中删除(set::erase),然后重新插入新项目(std::insert)使用新值。

值得指出的是,如果您使用的是vs 2008,
std::set
实现支持非常量迭代器,使您描述的代码能够使用该库成功编译,
set::const_iterator
set::iterator
属于同一类型,它们会抱怨显式设置新键值。

使用不同的比较谓词将其复制到自身中

std::set MySet();

/* add entries*/

MySet = std::set(MySet.begin(), MySet.end(), Comp);
通常,这用于指定不同的比较操作,例如使用存储类/结构的不同部分对其进行排序

如果集合中某个元素的值发生更改

停止!这是不合法的


std::set
不提供任何方法来执行您的请求,因为这已经是一个先决条件,永远不需要手动重新排序。

set迭代器在标准中是常量。如果您试图通过迭代器更新集合的成员,您应该会得到编译错误。注意,这将比删除单个项目,修改它,然后重新添加它。如果这会导致MySet中的更改,那已经是未定义的行为
std::set MySet();
不是变量。
是一个函数声明!!值不应该更改。
value\u type
应该是
std::set
(尽管我相信VS不遵守这一点?)值类型是用户传递的,并添加了一个顶级常量。如果用户传递
std::string*
,则值类型将是
std::string*const
。没有规则禁止用户传递不强制值排序位置不可变的内容;只有一条规则规定修改value以这种方式产生未定义的行为。