1

我在THIS THREAD中了解了如何将hashed_unique<>索引与 a composite_keyusing an int 和 a一起使用std::vector<int>。但不幸的是,以下代码会产生相当多的错误消息:

1> boost/multi_index/hashed_index.hpp(439) : error C2784: 'size_t .. composite_key_hash<...>::operator ()(const boost::tuples::tuple<...> &) const' :无法推断模板参数for 'const boost::tuples::tuple<...> &' from 'const unique_property'

代码在这里,有谁知道哪里错了?:-?

    #include <boost/multi_index_container.hpp>
    #include <boost/multi_index/hashed_index.hpp>
    #include <boost/multi_index/random_access_index.hpp>
    #include <boost/multi_index/mem_fun.hpp>
    #include <boost/multi_index/composite_key.hpp>

    #include <vector>

    using boost::multi_index_container;
    using namespace boost::multi_index;


    class unique_property
    {
    private:
      int  my_value;

      //the pair of int and std::vector<int> shall be unique
      int my_int;
      std::vector<int>  my_vec;

    public:
        //stupid ctor (my_values are unique as well, but thats not the point here)
        unique_property(int input_value)
        : my_value(input_value), my_int(10), my_vec(my_int,my_value)
        {}

        int get_int() const {return my_int;}
        const std::vector<int> & get_vec() const {return my_vec;}
    };



    struct hugo{};



    typedef multi_index_container<
      unique_property,
      indexed_by<
        hashed_unique< tag<hugo> ,// indexed by my_int and every entry of my_vec
          composite_key< 
            unique_property,
            const_mem_fun<unique_property,int,&unique_property::get_int >,
            const_mem_fun<unique_property,
                          const std::vector<int> &,&unique_property::get_vec >
          >
        >,
        random_access< >
      >
    > property_locator;

    // for brevity
    typedef property_locator::index<hugo>::type ProbLocByHugo;


    void dummy_test()
    {
        property_locator local_data_structure;
        unique_property tempy(5);

        ProbLocByHugo::iterator pos = local_data_structure.get<hugo>().find(tempy);

        //if (pos == local_data_structure.get<hugo>().end() )
        //    local_data_structure.insert(tempy);
        //else
        //{
        //    local_data_structure.get<hugo>().replace(pos,tempy);
        //}
    }

完整的错误消息是:

    1>------ Build started: Project: buggy, Configuration: Debug Win32 ------
    1>Compiling...
    1>c:\myPath\boost_1_37_0\include\boost-1_37\boost\multi_index\hashed_index.hpp(439) : error C2784: 'size_t boost::multi_index::composite_key_hash<Hash0,Hash1,Hash2,Hash3,Hash4,Hash5,Hash6,Hash7,Hash8,Hash9>::operator ()(const boost::tuples::tuple<Value0,Value1,Value2,Value3,Value4,Value5,Value6,Value7,Value8,Value9> &) const' : could not deduce template argument for 'const boost::tuples::tuple<Value0,Value1,Value2,Value3,Value4,Value5,Value6,Value7,Value8,Value9> &' from 'const unique_property'
    1>        with
    1>        [
    1>            Hash0=boost::hash<int>,
    1>            Hash1=boost::hash<const std::vector<int>>,
    1>            Hash2=boost::tuples::null_type,
    1>            Hash3=boost::tuples::null_type,
    1>            Hash4=boost::tuples::null_type,
    1>            Hash5=boost::tuples::null_type,
    1>            Hash6=boost::tuples::null_type,
    1>            Hash7=boost::tuples::null_type,
    1>            Hash8=boost::tuples::null_type,
    1>            Hash9=boost::tuples::null_type
    1>        ]
    1>        c:\myPath\boost_1_37_0\include\boost-1_37\boost\multi_index\composite_key.hpp(1099) : see declaration of 'boost::multi_index::composite_key_hash<Hash0,Hash1,Hash2,Hash3,Hash4,Hash5,Hash6,Hash7,Hash8,Hash9>::operator ()'
    1>        with
    1>        [
    1>            Hash0=boost::hash<int>,
    1>            Hash1=boost::hash<const std::vector<int>>,
    1>            Hash2=boost::tuples::null_type,
    1>            Hash3=boost::tuples::null_type,
    1>            Hash4=boost::tuples::null_type,
    1>            Hash5=boost::tuples::null_type,
    1>            Hash6=boost::tuples::null_type,
    1>            Hash7=boost::tuples::null_type,
    1>            Hash8=boost::tuples::null_type,
    1>            Hash9=boost::tuples::null_type
    1>        ]
    1>        c:\myPath\boost_1_37_0\include\boost-1_37\boost\multi_index\hashed_index.hpp(429) : see reference to function template instantiation 'boost::multi_index::detail::hashed_index_iterator<Node,BucketArray> boost::multi_index::detail::hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>::find<CompatibleKey,boost::hash<T>,std::equal_to<_Ty>>(const CompatibleKey &,const CompatibleHash &,const CompatiblePred &) const' being compiled
    1>        with
    1>        [
    1>            Node=boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::random_access_index_node<boost::multi_index::detail::index_node_base<unique_property,std::allocator<unique_property>>>>,
    1>            BucketArray=boost::multi_index::detail::bucket_array<std::allocator<unique_property>>,
    1>            KeyFromValue=boost::multi_index::composite_key<unique_property,boost::multi_index::const_mem_fun<unique_property,int,unique_property::get_int>,boost::multi_index::const_mem_fun<unique_property,const std::vector<int> &,unique_property::get_vec>>,
    1>            Hash=boost::hash<boost::multi_index::composite_key_result<boost::multi_index::composite_key<unique_property,boost::multi_index::const_mem_fun<unique_property,int,unique_property::get_int>,boost::multi_index::const_mem_fun<unique_property,const std::vector<int> &,unique_property::get_vec>>>>,
    1>            Pred=std::equal_to<boost::multi_index::composite_key_result<boost::multi_index::composite_key<unique_property,boost::multi_index::const_mem_fun<unique_property,int,unique_property::get_int>,boost::multi_index::const_mem_fun<unique_property,const std::vector<int> &,unique_property::get_vec>>>>,
    1>            SuperMeta=boost::multi_index::detail::nth_layer<1,unique_property,boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<hugo>,boost::multi_index::composite_key<unique_property,boost::multi_index::const_mem_fun<unique_property,int,unique_property::get_int>,boost::multi_index::const_mem_fun<unique_property,const std::vector<int> &,unique_property::get_vec>>>,boost::multi_index::random_access<>>,std::allocator<unique_property>>,
    1>            TagList=boost::mpl::vector1<hugo>,
    1>            Category=boost::multi_index::detail::hashed_unique_tag,
    1>            CompatibleKey=unique_property,
    1>            T=boost::multi_index::composite_key_result<boost::multi_index::composite_key<unique_property,boost::multi_index::const_mem_fun<unique_property,int,unique_property::get_int>,boost::multi_index::const_mem_fun<unique_property,const std::vector<int> &,unique_property::get_vec>>>,
    1>            _Ty=boost::multi_index::composite_key_result<boost::multi_index::composite_key<unique_property,boost::multi_index::const_mem_fun<unique_property,int,unique_property::get_int>,boost::multi_index::const_mem_fun<unique_property,const std::vector<int> &,unique_property::get_vec>>>,
    1>            CompatibleHash=boost::hash<boost::multi_index::composite_key_result<boost::multi_index::composite_key<unique_property,boost::multi_index::const_mem_fun<unique_property,int,unique_property::get_int>,boost::multi_index::const_mem_fun<unique_property,const std::vector<int> &,unique_property::get_vec>>>>,
    1>            CompatiblePred=std::equal_to<boost::multi_index::composite_key_result<boost::multi_index::composite_key<unique_property,boost::multi_index::const_mem_fun<unique_property,int,unique_property::get_int>,boost::multi_index::const_mem_fun<unique_property,const std::vector<int> &,unique_property::get_vec>>>>
    1>        ]
    1>        c:\documents and settings\amenge.dedekind\desktop\ggt_test\mem_rw_test.cpp(886) : see reference to function template instantiation 'boost::multi_index::detail::hashed_index_iterator<Node,BucketArray> boost::multi_index::detail::hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>::find<unique_property>(const CompatibleKey &) const' being compiled
    1>        with
    1>        [
    1>            Node=boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::random_access_index_node<boost::multi_index::detail::index_node_base<unique_property,std::allocator<unique_property>>>>,
    1>            BucketArray=boost::multi_index::detail::bucket_array<std::allocator<unique_property>>,
    1>            KeyFromValue=boost::multi_index::composite_key<unique_property,boost::multi_index::const_mem_fun<unique_property,int,unique_property::get_int>,boost::multi_index::const_mem_fun<unique_property,const std::vector<int> &,unique_property::get_vec>>,
    1>            Hash=boost::hash<boost::multi_index::composite_key_result<boost::multi_index::composite_key<unique_property,boost::multi_index::const_mem_fun<unique_property,int,unique_property::get_int>,boost::multi_index::const_mem_fun<unique_property,const std::vector<int> &,unique_property::get_vec>>>>,
    1>            Pred=std::equal_to<boost::multi_index::composite_key_result<boost::multi_index::composite_key<unique_property,boost::multi_index::const_mem_fun<unique_property,int,unique_property::get_int>,boost::multi_index::const_mem_fun<unique_property,const std::vector<int> &,unique_property::get_vec>>>>,
    1>            SuperMeta=boost::multi_index::detail::nth_layer<1,unique_property,boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::tag<hugo>,boost::multi_index::composite_key<unique_property,boost::multi_index::const_mem_fun<unique_property,int,unique_property::get_int>,boost::multi_index::const_mem_fun<unique_property,const std::vector<int> &,unique_property::get_vec>>>,boost::multi_index::random_access<>>,std::allocator<unique_property>>,
    1>            TagList=boost::mpl::vector1<hugo>,
    1>            Category=boost::multi_index::detail::hashed_unique_tag,
    1>            CompatibleKey=unique_property
    1>        ]
    1>c:\myPath\boost_1_37_0\include\boost-1_37\boost\multi_index\hashed_index.hpp(439) : error C2784: 'size_t boost::multi_index::composite_key_hash<Hash0,Hash1,Hash2,Hash3,Hash4,Hash5,Hash6,Hash7,Hash8,Hash9>::operator ()(const boost::multi_index::composite_key_result<CompositeKey1> &) const' : could not deduce template argument for 'const boost::multi_index::composite_key_result<CompositeKey1> &' from 'const unique_property'
    1>        with
    1>        [
    1>            Hash0=boost::hash<int>,
    1>            Hash1=boost::hash<const std::vector<int>>,
    1>            Hash2=boost::tuples::null_type,
    1>            Hash3=boost::tuples::null_type,
    1>            Hash4=boost::tuples::null_type,
    1>            Hash5=boost::tuples::null_type,
    1>            Hash6=boost::tuples::null_type,
    1>            Hash7=boost::tuples::null_type,
    1>            Hash8=boost::tuples::null_type,
    1>            Hash9=boost::tuples::null_type
    1>        ]
    1>        c:\myPath\boost_1_37_0\include\boost-1_37\boost\multi_index\composite_key.hpp(1083) : see declaration of 'boost::multi_index::composite_key_hash<Hash0,Hash1,Hash2,Hash3,Hash4,Hash5,Hash6,Hash7,Hash8,Hash9>::operator ()'
    1>        with
    1>        [
    1>            Hash0=boost::hash<int>,
    1>            Hash1=boost::hash<const std::vector<int>>,
    1>            Hash2=boost::tuples::null_type,
    1>            Hash3=boost::tuples::null_type,
    1>            Hash4=boost::tuples::null_type,
    1>            Hash5=boost::tuples::null_type,
    1>            Hash6=boost::tuples::null_type,
    1>            Hash7=boost::tuples::null_type,
    1>            Hash8=boost::tuples::null_type,
    1>            Hash9=boost::tuples::null_type
    1>        ]
    1>c:\myPath\boost_1_37_0\include\boost-1_37\boost\multi_index\hashed_index.hpp(443) : error C2784: 'bool boost::multi_index::composite_key_equal_to<Pred0,Pred1,Pred2,Pred3,Pred4,Pred5,Pred6,Pred7,Pred8,Pred9>::operator ()(const boost::tuples::tuple<Value0,Value1,Value2,Value3,Value4,Value5,Value6,Value7,Value8,Value9> &,const boost::multi_index::composite_key_result<CompositeKey> &) const' : could not deduce template argument for 'const boost::tuples::tuple<Value0,Value1,Value2,Value3,Value4,Value5,Value6,Value7,Value8,Value9> &' from 'const unique_property'
    1>        with
    1>        [
    1>            Pred0=std::equal_to<int>,
    1>            Pred1=std::equal_to<const std::vector<int>>,
    1>            Pred2=boost::tuples::null_type,
    1>            Pred3=boost::tuples::null_type,
    1>            Pred4=boost::tuples::null_type,
    1>            Pred5=boost::tuples::null_type,
    1>            Pred6=boost::tuples::null_type,
    1>            Pred7=boost::tuples::null_type,
    1>            Pred8=boost::tuples::null_type,
    1>            Pred9=boost::tuples::null_type
    1>        ]
    1>        c:\myPath\boost_1_37_0\include\boost-1_37\boost\multi_index\composite_key.hpp(914) : see declaration of 'boost::multi_index::composite_key_equal_to<Pred0,Pred1,Pred2,Pred3,Pred4,Pred5,Pred6,Pred7,Pred8,Pred9>::operator ()'
    1>        with
    1>        [
    1>            Pred0=std::equal_to<int>,
    1>            Pred1=std::equal_to<const std::vector<int>>,
    1>            Pred2=boost::tuples::null_type,
    1>            Pred3=boost::tuples::null_type,
    1>            Pred4=boost::tuples::null_type,
    1>            Pred5=boost::tuples::null_type,
    1>            Pred6=boost::tuples::null_type,
    1>            Pred7=boost::tuples::null_type,
    1>            Pred8=boost::tuples::null_type,
    1>            Pred9=boost::tuples::null_type
    1>        ]
    1>c:\myPath\boost_1_37_0\include\boost-1_37\boost\multi_index\hashed_index.hpp(443) : error C2784: 'bool boost::multi_index::composite_key_equal_to<Pred0,Pred1,Pred2,Pred3,Pred4,Pred5,Pred6,Pred7,Pred8,Pred9>::operator ()(const boost::multi_index::composite_key_result<CompositeKey1> &,const boost::tuples::tuple<Value0,Value1,Value2,Value3,Value4,Value5,Value6,Value7,Value8,Value9> &) const' : could not deduce template argument for 'const boost::multi_index::composite_key_result<CompositeKey1> &' from 'const unique_property'
    1>        with
    1>        [
    1>            Pred0=std::equal_to<int>,
    1>            Pred1=std::equal_to<const std::vector<int>>,
    1>            Pred2=boost::tuples::null_type,
    1>            Pred3=boost::tuples::null_type,
    1>            Pred4=boost::tuples::null_type,
    1>            Pred5=boost::tuples::null_type,
    1>            Pred6=boost::tuples::null_type,
    1>            Pred7=boost::tuples::null_type,
    1>            Pred8=boost::tuples::null_type,
    1>            Pred9=boost::tuples::null_type
    1>        ]
    1>        c:\myPath\boost_1_37_0\include\boost-1_37\boost\multi_index\composite_key.hpp(889) : see declaration of 'boost::multi_index::composite_key_equal_to<Pred0,Pred1,Pred2,Pred3,Pred4,Pred5,Pred6,Pred7,Pred8,Pred9>::operator ()'
    1>        with
    1>        [
    1>            Pred0=std::equal_to<int>,
    1>            Pred1=std::equal_to<const std::vector<int>>,
    1>            Pred2=boost::tuples::null_type,
    1>            Pred3=boost::tuples::null_type,
    1>            Pred4=boost::tuples::null_type,
    1>            Pred5=boost::tuples::null_type,
    1>            Pred6=boost::tuples::null_type,
    1>            Pred7=boost::tuples::null_type,
    1>            Pred8=boost::tuples::null_type,
    1>            Pred9=boost::tuples::null_type
    1>        ]
    1>c:\myPath\boost_1_37_0\include\boost-1_37\boost\multi_index\hashed_index.hpp(443) : error C2784: 'bool boost::multi_index::composite_key_equal_to<Pred0,Pred1,Pred2,Pred3,Pred4,Pred5,Pred6,Pred7,Pred8,Pred9>::operator ()(const boost::multi_index::composite_key_result<CompositeKey1> &,const boost::multi_index::composite_key_result<CompositeKey2> &) const' : could not deduce template argument for 'const boost::multi_index::composite_key_result<CompositeKey1> &' from 'const unique_property'
    1>        with
    1>        [
    1>            Pred0=std::equal_to<int>,
    1>            Pred1=std::equal_to<const std::vector<int>>,
    1>            Pred2=boost::tuples::null_type,
    1>            Pred3=boost::tuples::null_type,
    1>            Pred4=boost::tuples::null_type,
    1>            Pred5=boost::tuples::null_type,
    1>            Pred6=boost::tuples::null_type,
    1>            Pred7=boost::tuples::null_type,
    1>            Pred8=boost::tuples::null_type,
    1>            Pred9=boost::tuples::null_type
    1>        ]
    1>        c:\myPath\boost_1_37_0\include\boost-1_37\boost\multi_index\composite_key.hpp(859) : see declaration of 'boost::multi_index::composite_key_equal_to<Pred0,Pred1,Pred2,Pred3,Pred4,Pred5,Pred6,Pred7,Pred8,Pred9>::operator ()'
    1>        with
    1>        [
    1>            Pred0=std::equal_to<int>,
    1>            Pred1=std::equal_to<const std::vector<int>>,
    1>            Pred2=boost::tuples::null_type,
    1>            Pred3=boost::tuples::null_type,
    1>            Pred4=boost::tuples::null_type,
    1>            Pred5=boost::tuples::null_type,
    1>            Pred6=boost::tuples::null_type,
    1>            Pred7=boost::tuples::null_type,
    1>            Pred8=boost::tuples::null_type,
    1>            Pred9=boost::tuples::null_type
    1>        ]
4

2 回答 2

3

Matthieu 暗示了这个问题,但可能没有明确指出它: find() 需要一个兼容的键,而您正在传递整个元素。你如何从中提取密钥tempy?有两种方法:

  • 如 Matthieu 所示,构建一个兼容的元组。
  • 每个索引都提供一个key_extractor()成员函数,该函数返回内部键提取器的副本(此处为 的值composite_key<...>)供您使用:

ProbLocByHugo::iterator pos = local_data_structure.get<hugo>().find( local_data_structure.get<hugo>().key_extractor()(tempy));

希望这可以帮助。

于 2009-11-17T17:52:03.363 回答
1

好的,让我们开始工作(评论只允许这么多)。

问题源于方法的调用find

选出的模板为:

template<
  typename CompatibleKey,typename CompatibleHash,typename CompatiblePred
>
iterator find(const CompatibleKey& k,
              const CompatibleHash& hash,
              const CompatiblePred& eq) const;

和:

KeyFromValue = composite_key<...>
CompatibleKey = unique_property
CompatibleHash = boost::hash<KeyFromValue>
CompatiblePred = equal_to<KeyFromValue>

显然,由于引用的原因(无法推断......),方法hash(k)内部的调用失败,此方法本身调用:find

template<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)>
std::size_t operator()(const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x)const

(不要害怕宏,它只是一些神奇的 Boost.Preprocessor 来枚举Value从 0 到 9)

现在,从这里我们可以看出,问题在于我们尝试tuple<Value0, Value1, ..., Value9>CompatibleKeyie构建unique_property,但它不起作用。

我认为你应该尝试:

ProbLocByHugo::iterator pos =
  local_data_structure.get<hugo>().find(boost::make_tuple(tempy));

以下是composite_key来自 [Boost][1] 的示例:

file_system_by_name::iterator it=fs.find(
  boost::make_tuple(current_dir,dir));

boost::tie(it0,it1)=fs_by_size.equal_range(
    boost::make_tuple(current_dir));

如您所见,任何对密钥用法的调用都会导致make_tuple.

unique_property您可以通过为您的类提供正确的转换运算符来避免这种情况。

operator boost::tuple< int, std::vector<int> const& >() const
  { return boost::make_tuple(my_int, cref(my_vec)); }

或者也许是一个变化......

我不得不承认我对这个要求有点失望,我原以为它find会无缝地工作。

[1] http://www.boost.org/doc/libs/1_40_0/libs/multi_index/example/composite_keys.cpp

于 2009-11-17T08:33:50.430 回答