c++ - 类成员容器迭代器在成员函数 std::find 中不兼容,但为什么不呢?

标签 c++ visual-c++ c++11 visual-studio-2012

我遇到了一些我似乎无法理解的行为。假设我有一个定义如下的类(一个简单的说明示例):

class some_class
{
   public:
        some_class()
        {
            x_["0"] = "0";
            x_["1"] = "1";

            y_[0] = x_.find("0");
            y_[1] = x_.find("1");
        }

        int some_function(int i)
        {
            if(std::find(y_.begin(), y_.end(), x_.find("1")) != y_.end())
            {
                std::cout << "Found!" << std::endl;

                return 1001;
            }

            return -1001;
        }

   private:
       std::unordered_map<string, string> x_;
       std::array<unordered_map<string, string>::iterator, 2> y_;
};

代码在 Debug模式下使用 Visual Studio 2012 RC 编译(其他模式未测试),但在调用 some_function 期间程序失败并显示以下断言消息

... microsoft visual studio 11.0\vc\include\list Line: 289

Expression: list iterators incompatible...

调用代码如下所示

auto vector<int> as;
as.push_back(1);   

auto vector<int> bs;   
auto some = some_class();

std::transform(as.begin(), as.end(), std::inserter(bs, bs.begin()), [=](int i) { return  some.some_function(i); });

问题:

这样的安排会有什么问题?如果我在 some_function 中声明 x_y_ 而不是作为成员变量,我可以使代码运行良好。该类在 std::transform 之类的场合被调用/使用,如果应该考虑到这种情况的话。

顺便说一句,看起来下面的声明会被编译器拒绝,应该拒绝吗?

std::unordered_map<string, string> x_;
std::array<decltype(x_.begin()), 2> y_;

错误信息是

error C2228: left of '.begin' must have class/struct/union

最佳答案

你的情况。

#include <unordered_map>
#include <array>
#include <iostream>
#include <string>

class some_class
{
   public:
        some_class()
        {
            x_["0"] = "0";
            x_["1"] = "1";

            y_[0] = x_.find("0");
            y_[1] = x_.find("1");
        }

        int some_function()
        {
            if(std::find(y_.begin(), y_.end(), x_.find("1")) != y_.end())
            {
                std::cout << "Found!" << std::endl;

                return 1001;
            }

            return -1001;
        }

   private:
       std::unordered_map<std::string, std::string> x_;
       std::array<std::unordered_map<std::string, std::string>::iterator, 2> y_;
};

void function(some_class cl)
{
    cl.some_function();
}

int main()
{
    some_class c;
    function(c);
}

您的迭代器 指向另一个map 的元素,它在copy-ctor 之后存储在this 中,并且在find中有比较。

    bool operator==(const _Myiter& _Right) const
        {   // test for iterator equality
 #if _ITERATOR_DEBUG_LEVEL == 2
        if (this->_Getcont() == 0
            || this->_Getcont() != _Right._Getcont())
            {   // report error
            _DEBUG_ERROR("list iterators incompatible");
            _SCL_SECURE_INVALID_ARGUMENT;
            }

对于 decltype -

std::unordered_map<string, string> x_;
std::array<decltype(x_.begin()), 2> y_;

class-block 中不正确,因为没有对象。如果 x_ 将是 static,这将起作用。

关于c++ - 类成员容器迭代器在成员函数 std::find 中不兼容,但为什么不呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11705199/

相关文章:

c++ - Ref 限定的成员函数设计打破了 const 右值

c++ - 将元组转换为 "triangular"元组

c++ - std::transform 产生奇怪的输出

c++ - glReadPixels 移动坐标缩放

c++ - 压缩成员的引用地址不等于压缩成员的地址?

c++ - 分配大小无效 - 对象变量

c++ - 如何正确重写 ASSERT 代码以在 msvc 中传递/分析?

c++ - 当前函数地址 - x64

c++ - 理解 OpenCV 的 undistort 函数

c++ - 嵌套模板 gcc 编译器 4.1.2 错误