迭代器是否需要按标准包含容器中的任何类型信息?

时间:2016-03-17 09:19:27

标签: c++ iterator std

今天我遇到了this问题并开始怀疑gcc / clang和Visual Studio之间的不一致。

问题本身非常笼统,但我仍然想理解 - 标准是否对迭代器类型是否应该包含任何容器特定类型信息施加任何规则。请考虑以下代码段:

#include <unordered_map>
#include <iostream>

struct hash1
{
    size_t operator()(int key) const
    {
        return key;
    }
};

struct hash2
{
    size_t operator()(int key) const
    {
        return key + 1;
    }

};

int main(int argc, char** argv)
{
    std::unordered_map<int, int, hash1> map1;
    map1[1] = 1;
    std::unordered_map<int, int, hash2> map2;
    map2[1] = 1;
    std::unordered_map<int, int, hash2>::iterator it1 = map1.find(1);
    std::unordered_map<int, int, hash2>::iterator it2 = map2.find(1);
    if (it1 == it2) // Visual Studio 2015 Gives an assertion on iterator type inequality
    {
        std::cout << "equal";
    }
    else
    {
        std::cout << "not equal";
    }
}

因此在Visual Studio中,std::unordered_set迭代器类型只是一个std::list迭代器,当然它对哈希函数类型一无所知,因此我可以执行赋值,然后是等于运算符由于内部比较容器,因此给出断言。另一方面,GCC / clang也忽略了类型不兼容,但也没有运行时警告/错误。

该标准对此主题有何看法?

2 个答案:

答案 0 :(得分:4)

一对迭代器描述了值的序列。如果你尝试用两个没有指向相同序列元素的迭代器做某事,程序的行为是不确定的,即标准不对程序的作用施加任何要求。

请注意,前一段并未使用&#34; container&#34;任何地方。容器是创建序列的一种方式,但不是唯一的方法。所以,不,没有要求迭代器知道容器,因为迭代器没有与容器的固有连接。

答案 1 :(得分:2)

标准对此没有任何说明。它指定了std::unorderd_map<K, V, H, E, A>::iterator类型必须支持的操作。从std::unorderd_map<K, V, H1, E, A>::iterator构建可以不是其中之一(H1H不同)。因此,该标准对编译器必须如何处理包含这种结构的程序没有要求。因此,就标准而言,GCC和VS都很好。