简体   繁体   English

取消引用迭代器(C ++)

[英]Dereferencing iterator (c++)

I have problem with dereferencing result of operation that returns non-pointer value. 我在取消引用返回非指针值的操作结果方面遇到问题。

In this map i have pointers to matrixes 在此地图中,我有指向矩阵的指针

map<string, GeneralMatrix*> matrixes;

and this is how operations with matrixes look like 这就是矩阵运算的样子

GeneralMatrix & add(const GeneralMatrix & m2) {
        //Check for compatible matrixes
        if (height != m2.height || width != m2.width) {
            cout << "Matrix sizes must match!" << endl;
            return *this;
        }
        //Create new empty matrix
        GeneralMatrix &m3 = createNew(width, m2.height);
        //Set every number to sum of this and given matrix
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < m2.width; j++) {
                double val = m2.get(i, j);
                if (val != 0) {
                    val += get(i, j);
                    m3.set(i, j, val);
                }
            }
        }
        return m3;
    }

As you can see, add method returns non-pointer matrix that i want to insert into my map. 如您所见,add方法返回我要插入到地图中的非指针矩阵。

This is what I tried: 这是我尝试的:

map<string, GeneralMatrix *>::iterator itop1 , itop2;
//now seting iterators to their position

//there is the problem
matrixes.insert(pair<string, GeneralMatrix *>(result, (*itop1->second->add(*itop2->second)))); 

Problem is that i cant find out how to insert second parameter of pair. 问题是我找不到如何插入对的第二个参数。 It alway ends with error because of different types. 由于类型不同,它总是以错误结尾。

Attempt n1: 尝试n1:

itop1->second->add(itop2->second)

Add method needs pointer 添加方法需要指针

Attempt n2: 尝试n2:

itop1->second->add(*itop2->second)

Result is non-pointer, needs to be pointer 结果为非指针,需要为指针

Attemp n3: 尝试n3:

(*itop1->second->add(*itop2->second))

main.cpp:611:68: error: no match for 'operator*' (operand type is 'GeneralMatrix') main.cpp:611:68:错误:'operator *'不匹配(操作数类型为'GeneralMatrix')

How to derefence result then ? 那如何取消引用结果呢?

Ideally you would change matrixes to type map<string, GeneralMatrix> . 理想情况下,您可以将matrixes更改为map<string, GeneralMatrix>

Alternatively you could keep an std::list<GeneralMatrix> that stores the matrices and you give a pointer to the matrix inside the list. 或者,您可以保留存储矩阵的std::list<GeneralMatrix> ,并在列表中提供指向矩阵的指针。

It is considered bad style to have naked pointers. 裸露的指针被认为是不好的风格。 Pointers should instead tell the ownership status they have over the item, such as unique_ptr , shared_ptr or weak_ptr . 指针应该改为告知他们对该项目拥有的所有权状态,例如unique_ptrshared_ptrweak_ptr That would also take care of memory management. 那也将负责内存管理。

If your class is well behaved and the map holds owning pointers you could do something like this: 如果您的课堂表现良好,并且地图拥有自己的指针,则可以执行以下操作:

matrixes.insert(std::make_pair(std::string("name"), new GeneralMatrix(std::move(m)));

Where m is the matrix you are trying to move into the map. 其中m是您要移入地图的矩阵。

If the pointers in the map do not own the pointers you can just insert the address of the map with &m , but that requires you to store the matrix somewhere persistent such as the list shown above. 如果映射中的指针不拥有指针,则可以使用&m插入映射的地址,但这需要将矩阵存储在持久性位置,例如上面所示的list

Edit: Your specific problem with the iterator can be solved like this: 编辑:您的迭代器的特定问题可以这样解决:

matrixes.insert(pair<string, GeneralMatrix *>(result, &(*itop1)));

A quick solution to your problem is: 一个快速解决问题的方法是:

GeneralMatrix& m3= add(m2);
matrixes["string"] = &m3;
matrixes.insert(std::make_pair(std::string("name"), (&m3)));
matrixes.insert(std::make_pair<std::string, GeneralMatrix*>("name", &m3));

They are basically both equivalent in this case, however operator[] will always insert a value in the map, even if the right hand operator is null. 在这种情况下,它们基本上都是等效的,但是operator []将始终在映射中插入一个值,即使右侧的operator为null。 For example: 例如:

matrixes["s"]; 

will insert an empty pointer 将插入一个空指针

Your code however has several problems: 但是,您的代码有几个问题:

first, why do you need to return a reference from the method createNew? 首先,为什么需要从createNew方法返回引用? Just return a value to a new matrix. 只需将值返回到新矩阵即可。 You don't gain anything doing this. 您这样做不会有任何收获。

GeneralMatrix createNew(width, m2.height);

As suggested in another answer, have a map of string to unique_pointers instead of using raw pointers and/or leverage move semantics. 正如另一个答案所建议的那样,将字符串映射到unique_pointers,而不要使用原始指针和/或利用移动语义。 In your case, since an "add" operation will always result in creating a new matrix, I wouldn't even bother dealing with pointers, as they give you no real advantage 在您的情况下,由于“加”运算将始终导致创建新矩阵,因此我什至不必理会指针,因为它们没有给您带来真正的优势

Here you can find some stripped down code that will fit your needs: 在这里,您可以找到一些满足您需求的精简代码:

std::map<std::string, GeneralMatrix> matrixes;

GeneralMatrix add(const GeneralMatrix& m2)
{
    //Create new empty matrix
    auto m3 = createNew(width, m2.height);
    return m3;
}

Note also that this code will be optimized by your compiled, using something called NRVO (named return valueoptimization), and it will likely be faster that your previous one that dealt with dynamic allocation in the createNew method). 还要注意,此代码将由编译后使用称为NRVO(称为返回值优化)的东西进行优化,并且可能比以前的在createNew方法中处理动态分配的代码要快。 Now, if General matrix implements correctly the rvalue copy constructor you can move it to your map 现在,如果General矩阵正确实现了右值复制构造函数,则可以将其移至地图

map.insert(std::string("string"), std::move<m3>);

or you can just emplace it (not yet implemented by all compilers) 或者您也可以放置它(尚未由所有编译器实现)

map.emplace(std::make_pair(std::string("string"), createNew(m2)));

If you need polymorphism, just use a factory method that returns a base std::unique_ptr. 如果您需要多态,只需使用一种工厂方法,该方法将返回基本std :: unique_ptr。

std::unique_ptr<GeneralMatrix> createNew(width, m2.height);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM