在尝试解决问题时,我开始考虑这个问题 - 考虑到user-defined class
和2 comparators
,我们假设我们有2套std::set<user_class,comparator_inc>
和std::set<user_class,comparator_dec>
comparators
通过增加和减少user_class
(或许简单int
)中的值来排序。这是我的代码:
#include <iostream>
#include <set>
using std::cout;
using std::endl;
using std::set;
struct A
{
int val;
};
struct c_inc
{
bool operator()(const A& first,const A& second) const
{
return first.val > second.val;
}
};
struct c_dec
{
bool operator()(const A& first,const A& second) const
{
return first.val < second.val;
}
};
int main()
{
set<A,c_inc> s1;
set<A,c_dec> s2;
auto x = s1.insert({1});
cout << x.first->val << endl;
x = s2.insert({1});
x = s2.insert({0});
cout << x.first->val << endl;
}
我的问题是:是否定义了将x
重新分配给insert
的输出到具有相同set
但不同比较器的Key
的行为?这种用途有问题吗?它是在标准中定义的应该是什么,还是依赖于实现?
由于代码编译我认为两种情况下return
类型的insert
都是相同的 - 这个假设是正确的吗?
答案 0 :(得分:8)
我认为它依赖于实现。
从概念上讲,s1.insert
和s2.insert
的返回类型不同;特别是它们有不同的迭代器类型,即std::set<A,c_inc>::iterator
和std::set<A,c_dec>::iterator
。如何定义std::set::iterator
类型是实现定义的。
using iterator = implementation-defined; // see [container.requirements] using const_iterator = implementation-defined; // see [container.requirements]
答案 1 :(得分:3)
从技术上讲,你不应该依赖于此。
由于代码编译我认为两者都是insert的返回类型 案例是一样的 - 这个假设是正确的吗?
不,不是。想象一下这个简单的例子:
template<class T>
struct set {
struct iterator { /*...*/ };
};
在这种情况下,set<int>::iterator
肯定与set<double>::iterator
不同。
实现可以自由地将迭代器类型实现为一个自由类(因为迭代器不依赖于比较器),这似乎是主要实现中的情况,并且是什么允许你的例子。