简体   繁体   中英

Error while assigning a pair value to a map key

This is excerpt from my code:

std::map<int, std::pair< const int, const std::vector<POINT_3d> > > m_srcHitData;
void addHit( const int edgeId, const int hit )
{
  m_srcHitData[edgeId] = std::make_pair( hit, std::vector<POINT_3d>() );
}

I keep getting the error:

  stl_pair.h(180): error: no operator "=" matches these operands operand types are: const std::vector<POINT_3d, std::allocator<POINT_3d>> = const std::vector<POINT_3d, std::allocator<POINT_3d>> second = __p.second; ^ detected during instantiation of "std::pair<_T1, _T2> &std::pair<_T1, _T2>::operator=(const std::pair<_U1, _U2> &) 

What does that mean? I tried different approaches but still getting this or similar error. Thank you!

Well, m_srcHitData[edgeId] is a pair with a const vector member. You can't simply assign to it, because that means assigning to the const vector, which is not possible...

As for what you can do about it, see:

How to create a std::map of constant values which is still accessible by the [] operator?

As @FrancisCugler suggests, that could be, for example, writing:

m_srcHitData[edgeId].insert( std::make_pair( hit, std::vector<POINT_3d>() );

However, if your vectors are long, you might not actually want to copy all that data around.

This part in your code kind of looks ugly...

std::map<int, std::pair< const int, const std::vector<POINT_3d> > > m_srcHitData;

You could try restructuring your code a little.

struct Pair {
    unsigned int key_;
    std::vector<POINT_3d> points_;

    Pair() {} // Empty Default
    Pair( const unsigned int& key, const std::vector<POINT_3d>& points ) :
        key_(key),
        points_( points ) 
    {}
};

Then...

std::map<unsigned, Pair> m_srcHitData;

void addHit( const int edgeId, const int hit ) {
    m_srcHitData[edgeId] = Pair( hit, std::vector<POINT_3d>() );
}

I made this short program to simulate a similar structure only I used strings in place of your std::vector<POINT_3d>

#include <string>
#include <iostream>
#include <map>

struct Pair {
    unsigned key_;
    std::string value_;

    Pair() {}
    Pair( const unsigned int& key, const std::string& value ) :
        key_( key ),
        value_( value ) {}
};

class MyClass {
public:
    std::map<unsigned, Pair> myMap_;

    void addValue( const unsigned int& key, const std::string& value ) {
        myMap_[key] = Pair( key, value );
    }
};

int main() {

    MyClass myClass;
    myClass.addValue( 1, "Hello" );
    myClass.addValue( 2, "World" );

    typedef std::map<unsigned, Pair>::iterator Iter;
    Iter it = myClass.myMap_.begin();

    for ( ; it != myClass.myMap_.end(); ++it ) {
        std::cout << "Key: " << it->first << " Pair-Key: " << it->second.key_ << " Pair-value: " << it->second.value_ << std::endl;
    }


    std::cout << "\nPress any key and enter to quit." << std::endl;
    char c;
    std::cin >> c;
}

You can use the above, except substitute your objects of vector<T> with the strings .

I also used public interface on both the struct and class for simplicity of demonstration. Normally the container in the class would be either protected or private with accessory functions.

EDIT This is to help construct the map first. Once you have the map working then you can modify it to add in the const storage types if needed, but they can be tricky to work with. Refer to the link in einpoklum's answer.

If you are working with the newer versions of C++ you can change these lines of code:

typedef std::map<unsigned, Pair>::iterator Iter;
Iter it = myClass.myMap_.begin();

into this:

auto it = myClass.myMap_.begin();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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