2012-06-26 25 views
12

Tôi đã thiết lập dự án Visual Studio C++ (VS9) để kiểm tra việc sử dụng Boost :: Multi_Index. Vùng chứa đang được thiết lập để lưu trữ các con trỏ được chia sẻ với một đối tượng tùy chỉnh, FC :: ClientOrder. Để thử nghiệm, đối tượng rất đơn giản, chỉ lưu trữ một chuỗi và một biến char. Phiên bản tăng cường là 1_46_0C++ Boost Multi Index, Sửa đổi yêu cầu Functor, không biên dịch

Tôi đã định cấu hình vùng chứa Multi_Index để lập chỉ mục trên con trỏ được chia sẻ làm nhận dạng và cũng lập chỉ mục trên hai biến thành viên, sử dụng chức năng thành viên để truy cập. Điều đó có vẻ tốt và hoạt động tốt.

Tôi đang gặp sự cố với phương thức modify(). Tôi nhận ra tôi phải sử dụng sửa đổi() nếu tôi muốn cập nhật bất kỳ biến thành viên nào là một phần của chỉ mục. Tôi cũng nhận ra rằng tôi phải xác định đối tượng FC :: ClientOrder trong vùng chứa đầu tiên bằng cách sử dụng find(), và sau đó vượt qua vòng lặp để sửa đổi() để thực hiện thay đổi.

Nếu tôi tìm thấy con trỏ chia sẻ FC :: ClientOrder thông qua danh tính, con trỏ được chia sẻ, mọi thứ hoạt động tốt và sửa đổi() rất vui.

Nếu tôi tìm thấy con trỏ chia sẻ FC :: ClientOrder thông qua hàm thành viên, clOrdID() (về cơ bản tìm kiếm thứ tự trên ID của nó, sử dụng rất phổ biến) thì hàm modify() bị lỗi, mặc dù cú pháp giống hệt nhau . Tôi nhận được một lỗi biên dịch, mà dường như chỉ ra một vấn đề loại, nhưng tôi thấy khó để hiểu những gì là sai.

Liệu sửa đổi() chỉ hoạt động với một trình lặp dựa trên chỉ mục nhận dạng? Nếu vậy, để chỉnh sửa đơn đặt hàng qua clOrdID, tôi sẽ phải thực hiện hai lần tra cứu, một để tìm thứ tự trong vùng chứa (và lấy biến spOrder) và một để tạo một trình lặp dựa trên giá trị spOrder. Điều đó dường như đánh bại đối tượng của việc có thể kéo lên thứ tự thông qua giá trị clOrdID().

Tôi nghĩ rằng tôi đã hiểu sai chức năng sửa đổi() yêu cầu. Bây giờ, tôi có thể giải quyết vấn đề này bằng cách sử dụng tra cứu kép, nhưng nếu có ai đó có giải pháp, tôi sẽ đánh giá cao điều đó. Tôi khá mới để Functors vì vậy có lẽ tôi đã hiểu lầm những gì sửa đổi() nhu cầu.

Cảm ơn bạn trước vì đã trợ giúp, nó sẽ được đánh giá cao. Mẫu mã khối nên làm theo ...

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

// SOLUTION (cung cấp bởi stefaanv)

Tôi đã sử dụng sửa đổi() là một hàm thành viên của m_micOrders. Tôi nên đã được sử dụng sửa đổi() là một hàm thành viên của đối tượng chỉ số mà các iterator áp dụng cho, như vậy mà updateOrder() chức năng nên được sửa chữa để trông giống như này ...

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

Tôi không chắc chắn, vì vậy tôi không trả lời, nhưng tôi đoán là kể từ khi iterator là 'index (OrderMIC :: nth_index <1> :: loại) 'có lẽ bạn nên làm như sửa đổi trên' index': 'index.modify (i, FC :: ClientOrder :: change_status_by_sp (cOrdStatus));' (không được kiểm tra) – stefaanv

+2

Wow, vâng, đó là nó, bạn phải sử dụng đối tượng index như thế này ... "index index .modify (i, FC :: ClientOrder :: change_status_by_sp (cOrdStatus)); ", trái với việc sử dụng container m_micOrders. Bạn có muốn đăng câu trả lời để nhận tín dụng không? Cảm ơn rất nhiều, điều này đã thực sự khai sáng cho tôi, tôi có thể thấy rằng các phương pháp khác sẽ hoạt động tương tự. –

+0

Và bây giờ tôi có thể thấy rằng việc sử dụng m_micOrders trong chức năng làm việc chỉ hoạt động vì nó sử dụng danh tính, các mục chứa. Tất cả bây giờ đã có ý nghĩa hơn rất nhiều. Điều này đã làm cho ngày của tôi, cảm ơn StefaanV. –

Trả lời

0

(Giải pháp cung cấp . bởi stefaanv sao chép từ câu hỏi ban đầu tôi đặt nghe này để các câu hỏi không hiển thị như chưa có ai trả nữa @Steve Hibbert:. Hãy để sao chép đó cho mình một lần nữa như câu trả lời khác và chấp nhận nó)

. modify() được sử dụng làm chức năng thành viên của m_micOrders. Thay vào đó, modify() nên đã được sử dụng như một hàm thành viên của đối tượng chỉ mục mà trình vòng lặp áp dụng, sao cho các hàm updateOrder() phải được sửa chữa để trông giống như thế này ...

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; 
    } 
Các vấn đề liên quan