Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么std::(multi)set提供非常量迭代器方法_C++_C++11_Iterator_Set_Stdset - Fatal编程技术网

C++ 为什么std::(multi)set提供非常量迭代器方法

C++ 为什么std::(multi)set提供非常量迭代器方法,c++,c++11,iterator,set,stdset,C++,C++11,Iterator,Set,Stdset,通过迭代器访问密钥总是常量。集合本身是否为常量并不重要。为什么要引入这些额外的重载?虽然我不能肯定,但@yurikilochek的评论对我来说似乎是合理的。如果没有这些非常量迭代器方法,您能给出一个通用代码的例子吗?以下代码不使用libstdc++编译,而是在Visual Studio下编译,因为set没有非常量方法。我承认这不是一天中有人会写的代码 #include <iostream> #include <vector> #include <set> t

通过迭代器访问密钥总是常量。集合本身是否为常量并不重要。为什么要引入这些额外的重载?

虽然我不能肯定,但@yurikilochek的评论对我来说似乎是合理的。如果没有这些非常量迭代器方法,您能给出一个通用代码的例子吗?以下代码不使用libstdc++编译,而是在Visual Studio下编译,因为set没有非常量方法。我承认这不是一天中有人会写的代码

#include <iostream>
#include <vector>
#include <set>

template <class C> //C is some container
void f(C& c)
{
    typedef typename C::iterator iter;
    typedef iter (C::*fn)(); // note non-const method

    fn begin = &C::begin; // will fail with set if begin() is const only
    fn end = &C::end;

    for (iter i = (c.*begin)(), e = (c.*end)(); i != e; ++i)
        std::cout << *i << ' ';
    std::cout << '\n';
}

int
main()
{
    std::vector<int> v;
    std::set<int> s;

    f(v);
    f(s);

    return 0;
}
注意,在中,表示为:

在C++标准库中描述的非虚成员函数,一个实现可以声明一组不同的成员函数签名,前提是对从该文档中描述的声明集合中选择过载的成员函数的任何调用都表现为好像选择了过载。 本标准定义了每个容器的行为,其中要求:

a、 begin为常数a生成一个迭代器或常量迭代器 a、 end生成常量a的迭代器或常量迭代器 ... 实现的要求是这些类型C::iterator和C::const_iterator存在,并且这些函数生成这些类型。这项要求并不是说这四个重载必须存在,也不是说这两个迭代器类型必须不同。需求就是行为

以下是set的一个完全一致的实现:

通过这种实现,所有的需求都得到了满足。这样就足够了。实际上,libstdc++就是这样实现的——两个迭代器是相同的,只有一个迭代器

为什么要引入这些额外的重载


没有额外的重载。或者至少,没有必要。这取决于实施者

@TemaniAfif这是该问题的重复吗?为了完整性和通用性,请遵守概念。@yurikilochek为什么仅仅为返回常量引用到包含值的对象提供常量方法还不够通用?如果没有这些非常量迭代器方法,您能给出一个通用代码的例子吗?我能想到的唯一一件事是,它具有检测非常量begin和end方法存在的部分专门化。@yurikilochek容器概念没有提到类必须具有非常量限定的begin和end方法,它只是说容器必须具有它们。布景是这样的。cbegin和cend是另一个故事,在C++11之前并不完全相关,修改了从集合中接受迭代器的操作,如erase和insert所需的非常量迭代器的提示版本。所以这可能是一个原因。
template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>>
class set {
public:
    struct iterator { ... };
    using const_iterator = iterator;

    iterator begin() const { ... };
    iterator end() const { ... };

    // other stuff
};