I learned in THIS THREAD how a hashed_unique<>
index can be used with a composite_key
using an int and a std::vector<int>
. But unfortunately the following code produces quite an error message:
1> boost/multi_index/hashed_index.hpp(439) : error C2784: 'size_t .. composite_key_hash<...>::operator ()(const boost::tuples::tuple<...> &) const' :
could not deduce template argumentfor 'const boost::tuples::tuple<...> &' from 'const unique_property'
Here the code, does anyone know whats wrong? :-?
#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);
//}
}
The complete error messages are:
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,Valu开发者_JAVA技巧e6,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> ]
Matthieu hints at the problem but probably does not expclicitly pinpoint it: find() expects a key or a compatible key and you're passing a whole element. How do you extract the key from tempy
? There are two ways:
- Construct a compatible tuple as Matthieu shows.
- Each index provides a
key_extractor()
member function that returns a copy of the internal key extractor (here, a value ofcomposite_key<...>
) for you to use:
ProbLocByHugo::iterator pos = local_data_structure.get<hugo>().find(
local_data_structure.get<hugo>().key_extractor()(tempy));
Hope this helps.
Okay Let's get working (comments just allow so much).
The problem stems from the invocation of the find
method.
The template elected is:
template<
typename CompatibleKey,typename CompatibleHash,typename CompatiblePred
>
iterator find(const CompatibleKey& k,
const CompatibleHash& hash,
const CompatiblePred& eq) const;
With:
KeyFromValue = composite_key<...>
CompatibleKey = unique_property
CompatibleHash = boost::hash<KeyFromValue>
CompatiblePred = equal_to<KeyFromValue>
Apparently, the invocation hash(k)
inside the find
method fails for the reason cited (could not deduce...), this methods itself invokes:
template<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)>
std::size_t operator()(const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x)const
(Don't be afraid by the macro, it's just some magic Boost.Preprocessor to enumerate the Value
from 0 to 9)
Now, from this we can see that the problem is that we try to build tuple<Value0, Value1, ..., Value9>
from CompatibleKey
ie unique_property
and it does not work.
I think you should try:
ProbLocByHugo::iterator pos =
local_data_structure.get<hugo>().find(boost::make_tuple(tempy));
Here is the example of composite_key
from [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));
As you can see, any invocation of key usage leads to make_tuple
.
You could avoid this by providing the right conversion operator for your unique_property
class.
operator boost::tuple< int, std::vector<int> const& >() const
{ return boost::make_tuple(my_int, cref(my_vec)); }
Or perhaps a variation...
I have to admit that I am a bit disappointed by this requirement, I would have expected that find
would work seemlessly.
[1] http://www.boost.org/doc/libs/1_40_0/libs/multi_index/example/composite_keys.cpp
精彩评论