2012-04-30 48 views
1

我一直试图用boost::multi_index_container来解决我遇到的问题。但是,multi_index_container甚至无法编译声明。这个错误在MPL函数中很深,我不知道错误在哪里。使用boost :: multi_index_container

boost::multi_index_container< 
    NodeType, 
    boost::multi_index::indexed_by< 
     boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>, decltype(node_comparator)>, 
     boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>> 
    > 
> open_set(
    boost::make_tuple(node_comparator) 
); 

在这种情况下,node_comparator是拉姆达以及NodeType本身已经具备了专业化std::hash。这里是错误的文字:

1>d:\backups\code\boost_1_47_0\boost\multi_index\detail\node_type.hpp(56): error C2903: 'node_class' : symbol is neither a class template nor a function template 
1>   d:\backups\code\boost_1_47_0\boost\mpl\aux_\preprocessed\plain\apply_wrap.hpp(49) : see reference to class template instantiation 'boost::multi_index::detail::index_node_applier::apply<IndexSpecifierIterator,Super>' being compiled 
1>   with 
1>   [ 
1>    IndexSpecifierIterator=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,0>, 
1>    Super=boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>> 
1>   ] 
1>   d:\backups\code\boost_1_47_0\boost\mpl\aux_\preprocessed\plain\bind.hpp(207) : see reference to class template instantiation 'boost::mpl::apply_wrap2<F,T1,T2>' being compiled 
1>   with 
1>   [ 
1>    F=boost::multi_index::detail::index_node_applier, 
1>    T1=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,0>, 
1>    T2=boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>> 
1>   ] 
1>   d:\backups\code\boost_1_47_0\boost\mpl\aux_\preprocessed\plain\apply_wrap.hpp(49) : see reference to class template instantiation 'boost::mpl::bind2<F,T1,T2>::apply<U1,U2>' being compiled 
1>   with 
1>   [ 
1>    F=boost::multi_index::detail::index_node_applier, 
1>    T1=boost::mpl::_2, 
1>    T2=boost::mpl::_1, 
1>    U1=boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>>, 
1>    U2=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,0> 
1>   ] 
1>   d:\backups\code\boost_1_47_0\boost\mpl\aux_\preprocessed\plain\apply.hpp(63) : see reference to class template instantiation 'boost::mpl::apply_wrap2<F,T1,T2>' being compiled 
1>   with 
1>   [ 
1>    F=boost::mpl::bind2<boost::multi_index::detail::index_node_applier,boost::mpl::_2,boost::mpl::_1>, 
1>    T1=boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>>, 
1>    T2=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,0> 
1>   ] 
1>   d:\backups\code\boost_1_47_0\boost\mpl\aux_\preprocessed\plain\reverse_iter_fold_impl.hpp(82) : see reference to class template instantiation 'boost::mpl::apply2<F,T1,T2>' being compiled 
1>   with 
1>   [ 
1>    F=boost::mpl::bind2<boost::multi_index::detail::index_node_applier,boost::mpl::_2,boost::mpl::_1>, 
1>    T1=boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>>, 
1>    T2=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,0> 
1>   ] 
1>   d:\backups\code\boost_1_47_0\boost\mpl\reverse_iter_fold.hpp(43) : see reference to class template instantiation 'boost::mpl::aux::reverse_iter_fold_impl<N,First,Last,State,BackwardOp,ForwardOp>' being compiled 
1>   with 
1>   [ 
1>    N=2, 
1>    First=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,0>, 
1>    Last=boost::mpl::v_iter<boost::mpl::vector2<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>,2>, 
1>    State=boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>, 
1>    BackwardOp=boost::mpl::bind2<boost::multi_index::detail::index_node_applier,boost::mpl::_2,boost::mpl::_1>, 
1>    ForwardOp=boost::mpl::protect<boost::mpl::arg<1>> 
1>   ] 
1>   d:\backups\code\boost_1_47_0\boost\multi_index\detail\node_type.hpp(70) : see reference to class template instantiation 'boost::mpl::reverse_iter_fold<Sequence,State,BackwardOp>' being compiled 
1>   with 
1>   [ 
1>    Sequence=boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>, 
1>    State=boost::multi_index::detail::index_node_base<NodeType,std::allocator<NodeType>>, 
1>    BackwardOp=boost::mpl::bind2<boost::multi_index::detail::index_node_applier,boost::mpl::_2,boost::mpl::_1> 
1>   ] 
1>   d:\backups\code\boost_1_47_0\boost\multi_index_container.hpp(75) : see reference to class template instantiation 'boost::multi_index::detail::multi_index_node_type<Value,IndexSpecifierList,Allocator>' being compiled 
1>   with 
1>   [ 
1>    Value=NodeType, 
1>    IndexSpecifierList=boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>>, 
1>    Allocator=std::allocator<NodeType> 
1>   ] 
1>   c:\repo\render\render\sim\simcontext.cpp(264) : see reference to class template instantiation 'boost::multi_index::multi_index_container<Value,IndexSpecifierList>' being compiled 
1>   with 
1>   [ 
1>    Value=NodeType, 
1>    IndexSpecifierList=boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>,Wide::Sim::`anonymous-namespace'::<lambda8>>,boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>>> 
1>   ] 

任何关于原因的建议?

编辑:几乎没有上下文要。但这里对于那些你们谁不能没有一个一个SSCCE:

#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/hashed_index.hpp> 

struct NodeType { 
    int x, y, z; 
    float g_score; 
    NodeType(int ax, int ay, int az) { 
     x = ax; 
     y = ay; 
     z = az;   
    } 
    NodeType() {} 
    bool operator==(const NodeType& other) const { 
     return x == other.x && y == other.y && z == other.z; 
    } 
}; 

template<> struct std::hash<NodeType> : public std::unary_function<const NodeType&, std::size_t> { 
    std::size_t operator()(const NodeType& node) const { 
     return std::hash<int>()(node.x * 100000 + node.y * 1000 + node.z); 
    } 
}; 
template<> struct boost::hash<NodeType> : public std::unary_function<const NodeType&, std::size_t> { 
    std::size_t operator()(const NodeType& node) const { 
     return std::hash<int>()(node.x * 100000 + node.y * 1000 + node.z); 
    } 
}; 

int main() { 
    auto h = [&](NodeType x) { 
     return 5.0f; // details irrelevant 
    };  
    auto node_comparator = [&](NodeType lhs, NodeType rhs) { 
     return lhs.g_score + h(lhs) < rhs.g_score + h(rhs); 
    }; 
    boost::multi_index_container< 
     NodeType, 
     boost::multi_index::indexed_by< 
      boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>, decltype(node_comparator)>, 
      boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>> 
     > 
    > open_set(
     boost::make_tuple(node_comparator) 
    ); 
} 

回答

2

在您的SSCCE帖子后:也许您忘了添加以下内容?

#include <boost/multi_index/ordered_index.hpp> 
#include <boost/multi_index/identity.hpp> 

除此之外,我不能在这里编译的代码,因为我的环境是预先C++ 11,但我还是设法使其工作加入缺失包括与常规的命名函数替换lambda表达式。注意:我不得不改变的open_set建设ARGS作为另一个答案解释:

#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/hashed_index.hpp> 
#include <boost/multi_index/ordered_index.hpp> 
#include <boost/multi_index/identity.hpp> 

struct NodeType { 
    int x, y, z; 
    float g_score; 
    NodeType(int ax, int ay, int az) { 
     x = ax; 
     y = ay; 
     z = az;   
    } 
    NodeType() {} 
    bool operator==(const NodeType& other) const { 
     return x == other.x && y == other.y && z == other.z; 
    } 
}; 

template<> struct boost::hash<NodeType> : public std::unary_function<const NodeType&,  std::size_t> { 
    std::size_t operator()(const NodeType& node) const { 
     return boost::hash<int>()(node.x * 100000 + node.y * 1000 + node.z); 
    } 
}; 

double h(NodeType x) { 
    return 5.0f; 
} 

bool node_comparator(NodeType lhs, NodeType rhs) { 
    return lhs.g_score + h(lhs) < rhs.g_score + h(rhs); 
} 

int main() { 
    typedef boost::multi_index_container< 
     NodeType, 
     boost::multi_index::indexed_by< 
      boost::multi_index::ordered_non_unique<boost::multi_index::identity<NodeType>, bool (*)(NodeType,NodeType)>, 
      boost::multi_index::hashed_unique<boost::multi_index::identity<NodeType>> 
     > 
    > open_set_t; 

    open_set_t open_set(
     boost::make_tuple(
      boost::make_tuple(
       boost::multi_index::identity<NodeType>(), 
       &node_comparator 
      ), 
      open_set_t::nth_index<1>::type::ctor_args() 
     ) 
    ); 
} 

附加说明:您的lambda函数是按值取NodeType S,我想他们会更有效,如果他们接受了他们的论据const NodeType& s。

0

试图想这个问题是这么少的情况下是什么让一个有趣的消遣,但降低你的机会,你会得到一个有用的答案。理想情况下,您应该提供一个完整的测试用例(即一个简短的可编译程序)来显示问题。无论如何,在黑暗中拍摄:你说NodeType有一个专门的std::hash专业化,但Boost.MultiIndex使用boost::hash作为其默认的哈希生成器。试着看那里。

+0

几乎没有上下文可以获得。但你是对的 - 我应该发布一个明确的SSCCE。 – Puppy

0

另一个瞎猜(我认为这是它):作为decltype(node_comparator)没有缺省构造你必须在open_set建设提供一个初始值(node_comparator本身)。这是你想要什么看似做的,但不正确:正确的方法如下(模潜在的错别字,更多的细节here):

typedef boost::multi_index_container< 
    NodeType, 
    ... 
> open_set_t; 

open_set_t open_set(
    boost::make_tuple(
    boost::make_tuple(
     boost::multi_index::identity<NodeType>(), 
     node_comparator 
    ), 
    open_set_t::nth_index<1>::type::ctor_args() 
) 
); 

鉴于使用lambda表达式这里规定的详细程度,我认为你最好编写一个使用定义的默认可构造比较器类而不是node_comparator

+0

我不能使用默认构造的比较器类,逻辑需要一些状态。该错误特别指的是类的实例 - 而不是构造函数。 – Puppy

相关问题