我已經建立了一個Windows C++ Visual Studio項目(VS9)來測試使用的Boost :: Multi_Index。 容器正在設置爲存儲指向自定義對象FC :: ClientOrder的共享指針。爲了測試,該對象非常簡單,僅存儲一個字符串和一個char變量。升壓版本是1_46_0c + + Boost多指標,修改要求函子,未能編譯
我已經配置了Multi_Index容器索引上的共享指針作爲身份,並且還指數上的兩個成員變量,使用成員函數來訪問。這看起來很好,效果很好。
我雖然具有與所述修改()方法中的問題。我意識到我必須使用modify(),如果我想更新任何成員變量是索引的一部分。我也意識到我必須首先使用find()找到容器中的FC :: ClientOrder對象,然後傳遞迭代器以修改()以進行更改。
如果我找到FC :: ClientOrder通過身份共享指針,共享指針本身,一切正常,並修改()是幸福的。
如果我通過成員函數clOrdID()(本質上查找它的ID順序,非常常見)找到FC :: ClientOrder共享指針,那麼即使語法相同,modify()函數也會失敗。我得到一個編譯器錯誤,這似乎表明類型問題,但我發現很難理解錯誤。
將修改()只基於身份索引的迭代工作?如果是這樣,要通過它的clOrdID編輯訂單,我將不得不做兩次查找,一個查找容器中的順序(並獲取它的spOrder變量),然後一個查找基於spOrder值創建一個迭代器。這似乎擊敗了能夠通過clOrdID()值拉起訂單的對象。
我想我誤會了修改()函數需要。現在,我可以通過使用雙重查找來解決此問題,但如果有人有解決方案,我將非常感激。我對Functors很新,所以也許我誤解了modify()需要什麼。
在此先感謝您的幫助,我們將不勝感激。示例代碼塊應遵循...
///////////////////////////////////////////////////////////////////////////////
// FILE #1: FCClientOrder.h
///////////////////////////////////////////////////////////////////////////////
#ifndef FCClientOrder_H
#define FCClientOrder_H
#include <string> // Changed to use std::string
////////////////////////////////////////////////////////////////////////////////
// ClientOrder v3: RAM definition of a market order - stripped out for testing
namespace FC
{
class ClientOrder
{
public:
ClientOrder(); // Default Ctor
virtual ~ClientOrder(); // Dtor
//////////////////////
// ACCESSOR FUNCTIONS
std::string clOrdID(void) const; // Get
void clOrdID(const std::string& sClOrdID); // Set
char ordStatus(void) const; // Get
void ordStatus(char cOrdStatus); // Set
///////////////////
// PUBLIC STATICS
static void change_status_static(std::tr1::shared_ptr<FC::ClientOrder> spOrder,char cOrdStatus); // Static method to change status
// Functor
struct change_status_by_sp
{
change_status_by_sp(char cOrdStatus) // Ctor
: _cOrdStatus(cOrdStatus)
{}
void operator()(std::tr1::shared_ptr<FC::ClientOrder> spOrder) // Functor
{ spOrder->ordStatus(_cOrdStatus); }
private:
char _cOrdStatus;
};
private:
////////////////////
// PRIVATE MEMBERS
std::string m_sClOrdID; // Client order ID
char m_cOrdStatus; // Order Status
}; // end of class ClientOrder
} // end of namespace FC
#endif // FCClientOrder_H
///////////////////////////////////////////////////////////////////////////////
// FILE #2: FCClientOrder.cpp
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "FCClientOrder.h"
namespace FC
{
ClientOrder::ClientOrder()
{ ordStatus('0'); }
ClientOrder::~ClientOrder() // Dtor
{}
///////////////////////////////////////////////////////////////////////////
// PUBLIC FUNCTIONS
//
void ClientOrder::change_status_static(std::tr1::shared_ptr<FC::ClientOrder> spOrder,char cOrdStatus)
{ spOrder->ordStatus(cOrdStatus); }
///////////////////////////////////////////////////////////////////////////
// GET/SET FUNCTIONS
//
std::string ClientOrder::clOrdID(void) const // Get Client Order ID
{ return m_sClOrdID; }
void ClientOrder::clOrdID(const std::string& sClOrdID)
{ m_sClOrdID = sClOrdID; }
char ClientOrder::ordStatus(void) const
{ return m_cOrdStatus; }
void ClientOrder::ordStatus(char cOrdStatus)
{ m_cOrdStatus = cOrdStatus; }
} // end of namespace FC
///////////////////////////////////////////////////////////////////////////////
// FILE #3: MIC Definition, and member declaration
///////////////////////////////////////////////////////////////////////////////
typedef std::tr1::shared_ptr<FC::ClientOrder> spClientOrder;
typedef boost::multi_index::multi_index_container
<
spClientOrder, // Contained type, shared pointer to ClientOrder
boost::multi_index::indexed_by
<
boost::multi_index::ordered_unique // 0 index - shared pointer index
<
boost::multi_index::identity<spClientOrder>,
std::less<spClientOrder>
> ,
boost::multi_index::ordered_unique // 1 index - ClientOrderID
<
boost::multi_index::const_mem_fun< FC::ClientOrder, std::string, &FC::ClientOrder::clOrdID >
> ,
boost::multi_index::ordered_non_unique // 2 index - Order Status
<
boost::multi_index::const_mem_fun< FC::ClientOrder, char, &FC::ClientOrder::ordStatus > ,
std::less<char>
>
>
> OrderMIC;
// Member in working class
OrderMic m_micOrders;
///////////////////////////////////////////////////////////////////////////////
// FILE #4: Utility Functions to update the MIC via .modify()
///////////////////////////////////////////////////////////////////////////////
bool XMLTestApp::updateOrder(spClientOrder spOrder,char cOrdStatus) // Order Status is an index, so you must modify via MIC member functions
{
OrderMIC::nth_index<0>::type& index = m_micOrders.get<0>();
OrderMIC::nth_index<0>::type::iterator i = index.find(spOrder);
OrderMIC::nth_index<0>::type::iterator iEnd = index.end();
if (i != iEnd)
{
// FOUND
// i points at the order to change
return m_micOrders.modify(i,FC::ClientOrder::change_status_by_sp(cOrdStatus));
}
return false;
}
bool XMLTestApp::updateOrder(const std::string& sClOrdID,char cOrdStatus) // Order Status is an index, so you must modify via MIC member functions
{
OrderMIC::nth_index<1>::type& index = m_micOrders.get<1>();
OrderMIC::nth_index<1>::type::iterator i = index.find(sClOrdID);
OrderMIC::nth_index<1>::type::iterator iEnd = index.end();
if (i != iEnd)
{
// FOUND
// Option1 - This works, but does another lookup via alternative fn
return updateOrder(*i,cOrdStatus); // <- Works
// Option2 - Attempt to use static fn, fails
//spClientOrder spOrder = *i;
//return m_micOrders.modify(i,FC::ClientOrder::change_status_static(spOrder,cOrdStatus));
// Option3 - Attempt to use *i as spOrder, fails
//return m_micOrders.modify(i,FC::ClientOrder::change_status_by_sp(cOrdStatus));
}
return false;
}
// FILE #5: Compile Error
1>------ Build started: Project: XMLTest, Configuration: Debug Win32 ------
1>Compiling...
1>XMLTestApp.cpp
1>c:\program files\microsoft visual studio\myprojects\xmltest\xmltest\xmltestapp.cpp(931) : error C2664: 'bool boost::multi_index::detail::ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>::modify<FC::ClientOrder::change_status_by_sp>(boost::multi_index::detail::bidir_node_iterator<Node>,Modifier)' : cannot convert parameter 1 from 'boost::multi_index::detail::bidir_node_iterator<Node>' to 'boost::multi_index::detail::bidir_node_iterator<Node>'
1> with
1> [
1> KeyFromValue=boost::multi_index::identity<FC::XMLTestApp::spClientOrder>,
1> Compare=std::less<FC::XMLTestApp::spClientOrder>,
1> SuperMeta=boost::multi_index::detail::nth_layer<1,FC::XMLTestApp::spClientOrder,boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::identity<FC::XMLTestApp::spClientOrder>,std::less<FC::XMLTestApp::spClientOrder>>,boost::multi_index::ordered_unique<boost::multi_index::const_mem_fun<FC::ClientOrder,std::string,::>>,boost::multi_index::ordered_non_unique<boost::multi_index::const_mem_fun<FC::ClientOrder,char,::;>,std::less<char>>>,std::allocator<FC::XMLTestApp::spClientOrder>>,
1> TagList=boost::mpl::vector0<boost::mpl::na>,
1> Category=boost::multi_index::detail::ordered_unique_tag,
1> Node=boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<FC::XMLTestApp::spClientOrder,std::allocator<FC::XMLTestApp::spClientOrder>>>>>,
1> Modifier=FC::ClientOrder::change_status_by_sp
1> ]
1> and
1> [
1> Node=boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<FC::XMLTestApp::spClientOrder,std::allocator<FC::XMLTestApp::spClientOrder>>>>
1> ]
1> and
1> [
1> Node=boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<FC::XMLTestApp::spClientOrder,std::allocator<FC::XMLTestApp::spClientOrder>>>>>
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>Build log was saved at "file://c:\Program Files\Microsoft Visual Studio\MyProjects\XMLTest\XMLTest\Debug\BuildLog.htm"
1>XMLTest - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
//溶液(stefaanv提供)
我是用修改()作爲m_micOrders的成員函數。我應該已經使用修改()作爲索引對象的成員函數迭代器適用於,使得updateOrder()函數應該被校正成這樣...
bool XMLTestApp::updateOrder(const std::string& sClOrdID,char cOrdStatus)
{
OrderMIC::nth_index<1>::type& index = m_micOrders.get<1>();
OrderMIC::nth_index<1>::type::iterator i = index.find(sClOrdID);
OrderMIC::nth_index<1>::type::iterator iEnd = index.end();
if (i != iEnd)
{
// FOUND
return index.modify(i,FC::ClientOrder::change_status_by_sp(cOrdStatus));
}
return false;
}
我不知道,所以我不回答,但我的猜測是,由於迭代器上'指數(OrderMIC :: nth_index <1> ::類型)'你應該做'了修改index':'index.modify(i,FC :: ClientOrder :: change_status_by_sp(cOrdStatus));'(未測試) – stefaanv
哇,是的,就是這樣,你必須像這樣使用索引對象...「return index .modify(i,FC :: ClientOrder :: change_status_by_sp(cOrdStatus));「,而不是使用容器m_micOrders。你想發佈信息作爲答案嗎?非常感謝,這真的啓發了我,我可以看到,其他方法將同樣工作。 –
現在我可以看到,在工作函數中使用m_micOrders只能工作,因爲它使用的是包含的項目標識。現在所有的都變得更有意義。這讓我的一天,感謝StefaanV。 –