2015-07-03 5 views
1

Я схожу с ума здесь. У меня есть поиск google, чтобы найти один единственный достойный пример, когда люди используют unordered_map вместе с классом enum и хеш-функцией без какой-либо удачи. Те, кому удается найти, всегда заканчивают тем, что говорят «использовать карту».C++ unordered_multimap insert hash

Я пытаюсь сделать следующее:

Enum class facing направление мой спрайт смотрит.

Enum class Action - действие, которое делает мой спрайт.

Animation - это класс, который содержит различные анимации, которые я буду называть позже.

Контейнер должен выглядеть следующим образом:

карта

Там может быть больше 1 ОБЛИЦОВОЧНАЯ на карте как ключ и может быть больше, чем один ACTION в паре.

Пример:

map<LEFT, pair<ATTACK, attackAnimation> 
map<LEFT, pair<IDLE, idleAnimation> 
map<LEFTUP, pair<IDLE, idleAnimation> 

Это является упрощенной Everything

#include <iostream> 
#include <unordered_map> 
#include <string> 
#include <memory> 

template <typename T> 
struct Hash 
{ 
    typedef typename std::underlying_type<T>::type underlyingType; 
    typedef typename std::hash<underlyingType>::result_type resultType; 
    resultType operator()(const T& arg) const 
    { 
     std::hash<underlyingType> hasher; 
     return hasher(static_cast<underlyingType>(arg)); 
    } 
}; 

class Animation 
{ 
private: 
    std::string str; 

public: 
    Animation(std::string _string) 
    { 
     this->str = _string; 
    } 

    std::string& GetString() 
    { 
     return this->str; 
    } 
}; 

class Bullshit 
{ 
public: 
    enum class Action 
    { 
     Attack, 
     Move 
    }; 

    enum class Facing 
    { 
     Right, 
     Up, 
     Left 
    }; 

    Bullshit() 
    { 

    } 

    std::unordered_multimap<Bullshit::Facing, std::pair<Bullshit::Action, std::unique_ptr<Animation>>,Hash<Bullshit::Facing>>& GetlistAnimation() 
    { 
     return this->listAnimation; 
    } 

private: 
    std::unordered_multimap<Bullshit::Facing, std::pair<Bullshit::Action, std::unique_ptr<Animation>>,Hash<Bullshit::Facing>> listAnimation; 
}; 


int main() 
{ 
    Bullshit bull; 
    auto myList = bull.GetlistAnimation(); 

    std::unique_ptr<Animation> anim(new Animation("test")); 
    myList.insert(std::make_pair(Bullshit::Facing::Up, std::make_pair(Bullshit::Action::Attack, std::move(anim)))); 

    std::cin.get(); 
    return 0; 
} 

Код ошибки:

error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>' 
1>   with 
1>   [ 
1>    _Ty=Animation 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1447) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr' 
1>   with 
1>   [ 
1>    _Ty=Animation 
1>   ] 
1>   This diagnostic occurred in the compiler generated function 'std::pair<_Ty1,_Ty2>::pair(const std::pair<_Ty1,_Ty2> &)' 
1>   with 
1>   [ 
1>    _Ty1=Bullshit::Action, 
1>    _Ty2=std::unique_ptr<Animation> 
1>   ] 

ответ

1

Здесь

auto myList = bull.GetlistAnimation(); 

тип выводится для myList является std::unordered_map<.....>, то есть, это не ссылка. И копия не может быть создана, потому что карта содержит unique_ptr s. Что вы имели в виду это

auto& myList = bull.GetlistAnimation(); 

или в C++ 14,

decltype(auto) myList = bull.GetlistAnimation(); 
+1

@nilo Не беспокойтесь, есть целые [беседы] (https://www.youtube.com/watch?v=wQxj20X-tIU) экспертов об этом беспорядке. – inf

+0

Интересно, действительно ли ОП хочет этого. Возвращение ссылки на частного участника практически делает его общедоступным. –

0

Проблема не имеет ничего общего с unordered_map или хеш-функции. Это std::unique_ptr, которое невозможно открыть, и ваш GetlistAnimation пытается скопировать его (косвенно).

Как с правильно исправить это зависит от того, чего вы хотите достичь.

быстрое решение было бы использовать вместо std::shared_ptr:

std::unordered_map<Bullshit::Facing, std::pair<Bullshit::Action, std::shared_ptr<Animation>>,Hash<Bullshit::Facing>>& GetlistAnimation() 
    { 
     return this->listAnimation; 
    } 

private: 
    std::unordered_map<Bullshit::Facing, std::pair<Bullshit::Action, std::shared_ptr<Animation>>,Hash<Bullshit::Facing>> listAnimation; 

[...]

std::shared_ptr<Animation> anim(new Animation("test")); 
myList.insert(std::make_pair(Bullshit::Facing::Up, std::make_pair(Bullshit::Action::Attack, anim))); 

(Кстати, вы должны использовать std::make_shared и std::make_unique.)


Исправить которые могут быть быстро и правильно (опять же, в зависимости от того, что вы хотите достичь), чтобы избавиться от логики указателя вообще и просто использовать Animation непосредственно:

std::unordered_map<Bullshit::Facing, std::pair<Bullshit::Action, Animation>,Hash<Bullshit::Facing>>& GetlistAnimation() 
    { 
     return this->listAnimation; 
    } 

private: 
    std::unordered_map<Bullshit::Facing, std::pair<Bullshit::Action, Animation>,Hash<Bullshit::Facing>> listAnimation; 

[...]

Animation anim("test"); 
myList.insert(std::make_pair(Bullshit::Facing::Up, std::make_pair(Bullshit::Action::Attack, anim))); 
+0

Спасибо за ваше время, чтобы ответить мне мат. Я заметил это, но проблема в моем коде была волнующей и после авто, которая завинчивала все, потому что я был так напряжен. –

Смежные вопросы