1

動的プロパティ マップを作成しようとしています。そのために、個々のプロパティ マップ Dynamic_attribute を作成し、それらを格納する std::unordered_map であるコンテナーを作成しました。以下は私が書いたコードです。しかし、g++ オプション -std=c++0x を使用してコンパイルすると、非常に奇妙なエラーが発生します。

#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <algorithm>
#include <string>
#include <typeinfo>
#include <cstdlib>
#include <cstring>
#include <boost/property_map/property_map.hpp>
#include <boost/property_map/dynamic_property_map.hpp>

class Dynamic_attribute_base{
public:
  Dynamic_attribute_base(const std::string& name) : name_(name){}

  /// Destructor
  virtual ~Dynamic_attribute_base(){}

  /// Destroy the object
  virtual void destroy() = 0;

protected:
  std::string name_;
};

/// @models
/// - LValuePropertyMap
/// - std:unordered_map
template<typename Key, typename Value>
class Dynamic_attribute
    : public Dynamic_attribute_base{
public:
  typedef Key key_type;
  typedef Value value_type;
  typedef std::unordered_map<key_type, value_type> map_type;
  typedef typename map_type::reference referencnce;
  typedef typename map_type::const_reference const_reference;

  /// Constructor
  Dynamic_attribute(const std::string& name):
    Dynamic_attribute_base(name) {}

public:  // virtual interface of Dynamic_attribute_base

  virtual void destroy(){
    data_.clear();
    this->~Dynamic_attribute();
  }
public:
  /// Return the value corresponding to key k.
  /// if key doesn't exists unexpected value is returned.
  value_type get(key_type& k){
    assert(!data_.empty());
    if (data_.find(k) != data_.end()){
      return data_[k];
    }
    else{
        std::cout<<"Key not found"<< std::endl;
        return NULL;
    }
  }

  /// Set the property corresponding to particular Key K
  /// to value V.
  void set(key_type& k, value_type& v){
    data_[k] = v;
  }

  /// Remove a key from the map.
  void remove(key_type& k){
    data_.erase(k);
  }

protected:
  map_type data_;
};

std::unordered_map< std::pair<std::string,unsigned int> , Dynamic_attribute_base*> d_attribute_container;
template<typename T>
void add_dynamic_attribute(unsigned int admin, std::string name){
  if (d_attribute_container.find(make_pair(name,admin)) != d_attribute_container.end()){
    std::cout<<"Error. Key already exists.";
    return;
    }
  Dynamic_attribute<int, T> *d_attr = new Dynamic_attribute<int, T>(name);
  d_attribute_container[make_pair(name,admin)] = d_attr;
}

template<typename T>
T get_dart_attribute(int handle, unsigned int admin, std::string name){
  if (d_attribute_container.find(make_pair(name,admin)) == d_attribute_container.end()){
      std::cout<<"Error. Key doesn't exists.";
      return;
    }
  return dynamic_cast<Dynamic_attribute<int,T>*>(d_attribute_container[make_pair(name,admin)])->get(handle);
}

int main()
{
  add_dynamic_attribute<std::string>(1,"first");
  add_dynamic_attribute<double>(2,"second");
  add_dynamic_attribute<double>(2,"second");
  return 0;
}

私が得たエラーメッセージ

/tmp/ccLK64Ja.o: 関数内std::__detail::_Hash_code_base<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int>, std::pair<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int> const, Dynamic_attribute_base*>, std::_Select1st<std::pair<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int> const, Dynamic_attribute_base*> >, std::equal_to<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int> >, std::hash<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_hash_code(std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int> const&) const': main.cpp:(.text._ZNKSt8__detail15_Hash_code_baseISt4pairISsjES1_IKS2_P22Dynamic_attribute_baseESt10_Select1stIS6_ESt8equal_toIS2_ESt4hashIS2_ENS_18_Mod_range_hashingENS_20_Default_ranged_hashELb0EE12_M_hash_codeERS3_[std::__detail::_Hash_code_base<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int>, std::pair<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int> const, Dynamic_attribute_base*>, std::_Select1st<std::pair<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int> const, Dynamic_attribute_base*> >, std::equal_to<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int> >, std::hash<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_hash_code(std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int> const&) const]+0x37): undefined reference tostd::hash, std::allocator >, unsigned int> >::operator()(std::pair, std::allocator >, unsigned int>) const'

何か案は?

4

1 に答える 1

1

ペアに特化するstd::hashか、代わりにハッシュテンプレート引数を提供する必要があります。

于 2012-07-05T10:38:08.953 に答える