2012-06-26 12 views
12

Boost :: Multi_Index kullanımını sınamak için bir Windows C++ Visual Studio projesi (VS9) oluşturdum. Kapsayıcı, paylaşımlı işaretçileri FC :: ClientOrder adlı özel bir nesneye depolayacak şekilde ayarlanmaktadır. Test için, nesne sadece bir string ve bir char değişkeni depolamak çok basittir. Yükseltme sürümü 1_46_0C++ Boost Çoklu Dizin, Değiştir, Functor, derlenemedi

Paylaşılan işaretçiyi kimlik olarak indekslemek için Multi_Index kapsayıcısını ve ayrıca üye üye işlevlerini kullanarak iki üye değişkeni de indekslemeyi yapılandırdım. Bu iyi görünüyor ve iyi çalışıyor.

Bununla birlikte, modify() yöntemiyle ilgili bir sorun yaşıyorum. Bir dizinin parçası olan herhangi bir üye değişkenini güncellemek istersem, change() 'i kullanmam gerektiğini anlıyorum. Ayrıca, ilk olarak find() kullanarak kapsayıcısında FC :: ClientOrder nesnesini bulmam gerektiğini ve sonra değişikliği yapmak için yineleyiciyi() değiştirmek için geçirdiğimi de fark ettim.

FC :: ClientOrder paylaşılan işaretçisini kimlik aracılığıyla paylaşırsam, paylaşılan işaretçinin kendisi, her şey iyi çalışır ve() mutludur.

FC :: ClientOrder paylaşılan işaretçisini üye işleviyle bulursam, clOrdID() (esas olarak kimliği üzerindeki sıralamayı ararken, çok yaygın kullanım), sözdizimi aynı olsa bile modify() işlevi başarısız olur. . Ben bir tür sorunu belirten bir derleyici hatası alıyorum, ama neyin yanlış olduğunu anlamakta zorlanıyorum.

Düzeltme() yalnızca kimlik dizinine dayalı bir yineleyici ile çalışır mı? Öyleyse, siparişi clOrdID aracılığıyla düzenlemek için, kapsayıcıdaki sırayı bulmak (ve spOrder değişkenini almak) için iki arama yapmalı ve sonra spOrder değerine dayanan bir yineleyici oluşturmalıyım. Bu, sırayı clOrdID() değeri üzerinden çekebilme nesnesi yenmek gibi görünüyor.

Sanırım, modify() işlevinin ne gerektirdiğini yanlış anlamıştım. Şimdilik, bu çifte aramayı kullanarak çalışabilirim, ama eğer bir çözüm varsa, bunu çok takdir ediyorum. Ben Functor'lar için oldukça yeniyim, bu yüzden belki de hangi modemin() ihtiyaç duyduğunu yanlış anladım.

Herhangi bir yardım için şimdiden teşekkür ederiz, büyük takdir edilecektir. Örnek kod parçaları ... (stefaanv tarafından sağlanan)

/////////////////////////////////////////////////////////////////////////////// 
// 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 ========== 

// ÇÖZÜM

Ben m_micOrders üyesi fonksiyonu olarak() değiştirmek kullanıyordum takip etmelidir. Ben

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; 
    } 
+5

emin değilim, o yüzden cevap vermeyeceğim, ama benim tahminim yineleyici indeksi 'yer alması sebebiyle (OrderMIC :: nth_index <1> :: tipi)' muhtemelen 'üzerinde değiştirme yapmak gerektiğidir index ':' index.modify (i, FC :: ClientOrder :: change_status_by_sp (cOrdStatus)); '(test edilmedi) – stefaanv

+2

Vay, evet, işte bu, indeks nesnesini bunun gibi kullanmalısın ..." iade endeksi .modify (i, FC :: ClientOrder :: change_status_by_sp (cOrdStatus)); ", m_micOrders kapsayıcıyı kullanmak yerine. Kredi almak için cevap olarak göndermek ister misiniz? Çok teşekkürler, bu beni gerçekten aydınladı, diğer yöntemlerin de benzer şekilde çalışacağını görebiliyorum. –

+0

Ve şimdi m_micOrders'ın çalışma işlevinde kullanılmasının, yalnızca içerdiği öğelerle ilgili olduğu için çalıştığını görebiliyorum. Artık hepsi daha mantıklı. Bu benim günüm oldu, teşekkürler StefaanV. –

cevap

0

(Çözüm sağlanan ... yineleyici updateOrder() işlevlerini şöyle görünecek şekilde düzeltilmelidir öyle ki, geçerli olduğu endeks nesnesinin bir üyesi fonksiyonu olarak() değiştirmek kullanarak olmalıydı . soru artık cevapsız olarak görünmüyor böylece asıl soruya kopyalanmış stefaanv tarafından bu duymak koymak @Steve Hibbert. başka cevap olarak tekrar kendini kopyalama ve onu kabul çekinmeyin)

. modify(), m_micOrders'un bir üye işlevi olarak kullanıldı. Bunun yerine, modify(), yineleyicinin uyguladığı dizin nesnesinin bir üyesi işlevi olarak kullanılmalıydı, öyle ki updateOrder() işlevleri bu gibi görünecek şekilde düzeltilmelidir ...

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; 
    }