how to convert map into set

2019-06-09 08:54发布

问题:

i got some issues trying to convert my map into a set I got a "Chanson" object with this member data :

std::map<std::string,Artiste*> m_interpretes;

Here is how i add my *Artiste to my map :

void Chanson::addArtiste(Artiste* a) throw (ExceptionArtiste, ExceptionLangueIncompatible)
{
    if(a!=NULL)
    {
        if(a->getLangue() == this->getLangue())
        {
            m_interpretes.insert(pair<string, Artiste*>(a->getNom(), a));
            //m_interpretes[a->getNom()] = a;
        }
        else
        {
            throw ExceptionLangueIncompatible(a,this);
        }
    }
}




set<Artiste*> Chanson::getArtistes() const
{
    //set<Artiste*> machin;
    return set<Artiste*> (m_interpretes.begin(), m_interpretes.end());
}

i got this error due to this function :

Error C2664: 'std::pair<_Ty1,_Ty2> std::set<_Kty>::insert(Artiste *&&) : impossible de convertir le paramètre 1 de const std::pair<_Ty1,_Ty2> en 'Artiste *&&' c:\program files (x86)\microsoft visual studio 11.0\vc\include\set 179 1

Any idea how to fix it?

回答1:

The std::set constructor you are trying to use will try to construct an element from everything the range you pass it:

return set<Artiste*> (m_interpretes.begin(), m_interpretes.end());

But the element type of that range is

std::pair<const std::string, Artiste*>

which is definitely not convertible to Artiste*, which is why you are getting that error about not being able to convert. You could just do it manually though:

std::set<Artiste*> s;
for (const auto& pair : m_interpretes) {
    s.insert(pair.second);
}


回答2:

The problem is here:

return set<Artiste*> (m_interpretes.begin(), m_interpretes.end());

If you have a look at the types you get from the map::begin() and map::end() functions you see that you get an iterator of std::pair<string, Artiste*>.

The problem is that the set::insert() function expects the iterators it is given to be of type Artiste*.

The simplest fix would be to create the set with a for loop, as shown in Barry's answer.



回答3:

A map is an associative data structure, while a set only contains unordered collection of items, so adding a pair (key, value) is invalid for the latter and only holds for the former.

To make a set of keys from a map, you can do

std::set<Artiste*> tempSet;
std::transform(m_interpretes.cbegin(), m_interpretes.cend(),
               std::inserter(tempSet, tempSet.begin()),
               [](const std::pair<std::string, Artiste*>& key_value)
               { return key_value.second; });
return tempSet;


标签: c++ map set