2012-04-30 47 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

相關問題