2013-03-28 12 views
6

यह प्रश्न निर्धारित प्रतिलिपि एक गैर प्रतिलिपि बनाने योग्य प्रकार बूस्ट संस्करणबढ़ावा :: संस्करण; std :: unique_ptr और

Tree वर्ग के साथ नहीं किया जा सकता कि

template <class T = int> 

class Tree{ 

private: 

     class TreeNode{ 

     public: 
       std::unique_ptr Nodes 
       Move constructors and move assignment + other public members 

     private: 

       TreeNode(const TreeNode &other);  (= delete not supported on compiler) 
       TreeNode& operator=(const TreeNode &rhs); (= delete not supported on compiler) 


     }; // End Tree Node Class Definition 


     Tree(const Tree &other);  (= delete not supported on compiler) 
     Tree& operator=(const Tree &rhs); (= delete not supported on compiler) 

public: 

     Move constructors and move assignment + other public members 
}; 

TreeVisitor वर्ग

class TreeVisitor : public boost::static_visitor<bool> { 
public: 
     TreeVisitor() {} 

     bool operator() (BinarySearchTree<std::string>& tree) const { 
      return searchTree.load(tree); 
     } 
private: 

}; 

TreeVariant

typedef boost::variant<Tree<std::string>, Tree<int>> TreeVariant;  
TreeVariant tree; 

Tree<std::string> stringTree; 
Tree<int> intTree; 

Visitors को लागू करने के रूप में भी वांछित मापदंडों के लिए बढ़ावा :: बाँध का उपयोग कर

tree = intSearchTree; 
boost::apply_visitor(TreeVisitor(), tree) 

इस प्रकार

प्रकार

error C2248: 'Tree<T>::Tree' : cannot access private member declared in class 'Tree<T>' <----- related to private copy constructor in Tree (not TreeNode) 
tree = stringTree; <------- error related to assignment 

Tree सही ढंग से संकलित करता है तथा परीक्षण किया गया है की

boost::bind(TreeVisitor(), tree, val, keyIndex); 

संकलक त्रुटियों । Tree कक्षा की एक प्रति प्राप्त करने की कोशिश करने से संबंधित इन संकलन त्रुटियों को मैं कैसे हल कर सकता हूं, std::unique_ptr की वजह से, यह संभव नहीं है?

SSCCE

<class T = int> 

class Tree{ 

private: 

class TreeNode{ 

public: 

    TreeNode() {} 
    ~TreeNode() {} 

    TreeNode(TreeNode &&other) : 
     key(other.key), index(other.index), left(std::move(other.left)), right(std::move(other.right)) 
    { 
     key = index = left = right = nullptr; 
    } 

    TreeNode &operator=(BTreeNode &&rhs) 
    { 
     if(this != &rhs) 
     { 
      key = rhs.key; index = rhs.index; 
      left = std::move(rhs.left); right = std::move(rhs.right); 
      rhs.key = rhs.index = rhs.left = rhs.right = nullptr; 
     } 
     return *this; 
    } 

    TreeNode(const T &new_key, const T &new_index) : 
     key(new_key), index(new_index), left(nullptr), right(nullptr) {} 

    friend class Tree; 

private: 

    TreeNode(const BinarySearchTreeNode &other); 
    TreeNode& operator=(const BinarySearchTreeNode &rhs); 

    std::unique_ptr<TreeNode> left; 
    std::unique_ptr<TreeNode> right; 

}; // End Tree Node Class Definition 

std::unique_ptr<TreeNode> root; 

BinarySearchTree(const BinarySearchTree &other); 
BinarySearchTree& operator=(const BinarySearchTree &rhs); 


public: 

Tree() : root(nullptr), flag(false), run(true), leftCount(0), rightCount(0) {} 

~Tree() {} 

Tree(BinarySearchTree &&other) : root(std::move(other.root)) { other.root = nullptr; } 

Tree &operator=(BinarySearchTree &&rhs) 
{ 
    if(this != &rhs) 
    { 
     root = std::move(rhs.root); 
     rhs.root = nullptr; 
    } 
    return *this; 
} 


}; 

उदाहरण उपयोग:

bool delete_(){ 

    while(!instances.empty()){ 
        // grab first instance 
        keyIndex = instances.at(0); 
        // compute end of the tuple to delete 
        endIndex = keyIndex + sizeToDelete; 

        // read the first attribute 
        try{ 
         temp = boost::trim_copy(dataFile->readData(keyIndex, domainSize)); 
        } 
        catch (std::exception &e){ 
         printw("Error reading from the data file"); 
        } 

        // delete tuple from data file 
        if(!dataFile->deleteTuple(keyIndex, endIndex)){ 
         printw("Error attempting to remove tuple"); 
         if (writer_ != nullptr) 
          writer_ << "Error attempting to remove tuple"; 
         try{ 
          printw("%s"); 
          // close catalog and search file 

         } 
         catch (std::exception &e){ 
          e.what(); 
         } 
         // close data file 
         dataFile->closeFile(); 
         return false; 
        } 


        try{ 
         int val = boost::lexical_cast<int>(temp); 

         searchTree = intSearchTree; 

         boost::bind(BinarySearchTreeVisitor(), searchTree, val, keyIndex); 

         // delete key index from the index file 
         if (!boost::apply_visitor(BinarySearchTreeVisitor(), searchTree)){ 
          printw("No index present in index file"); 
          try{ 
           printw(" "); 

          } 
          catch (std::exception &e){ 

          } 
          // close data file 
          dataFile->closeFile(); 
          return false;   
         } 
        } 
        catch(boost::bad_lexical_cast &e){ 

         /* 
         * Must be a std::string --- wow who knew 
         */ 

         searchTree = stringSearchTree; 

         boost::bind(BinarySearchTreeVisitor(), searchTree, temp, keyIndex); 

         // delete key index from the index file 
         if (!boost::apply_visitor(BinarySearchTreeVisitor(), searchTree)){ 
          printw("No index present in index file"); 
          try{ 
           printw(" "); 
           // close catalog and search file 

          } 
          catch (std::exception &e){ 
           e.what(); 
          } 
          // close data file 
          dataFile->closeFile(); 
          return false;   
         } 

        }      

        // clean up the index file 
        boost::bind(BinarySearchTreeVisitor(), searchTree, keyIndex, sizeToDelete); 
        boost::apply_visitor(BinarySearchTreeVisitor(), searchTree); 

        instances.erase(instances.begin()); 

        for(int i= 0; i < instances.size(); i++){ 
         instances.assign(i, instances.at(i) - 
                  sizeToDelete); 
        } 

       } 
} 
+2

पोस्ट कोड जो संकलित करता है, कृपया। (और अभी भी समस्या का प्रदर्शन करता है) उन चीज़ों को हटाएं जो महत्वपूर्ण नहीं हैं, लेकिन फिर भी समस्या का प्रदर्शन करते हैं। यहां देखें: http://sscce.org/ अपने प्रश्न को उत्तर देने में आसान बनाने के लिए कदम उठाने के लिए। – Yakk

+0

@Yakk मेरा मूल पोस्ट इस समस्या को स्पष्ट करता है जितना मैं दस वर्गों और कोड की हजारों पंक्तियों के कार्यक्रम के लिए कर सकता हूं। यह उतना ही अच्छा है जितना कि आपको विज्ञापन infinitum स्क्रॉल किए बिना मिलता है। – Mushy

+0

नहीं, यह नहीं है। आपका 'ट्रीविजिटर' 'बाइनरीशर्च ट्री' के बारे में बात कर रहा है, जो कि एक प्रकार है जो कहीं से बाहर नहीं आता है। क्या 'वृक्ष' को 'बाइनरीशर्च ट्री' माना जाता है? आपके लगभग 'delete_' फ़ंक्शन समस्या के लिए अप्रासंगिक है, आप इसे जितना छोटा कर सकते हैं उतना छोटा है? क्या 'TreeNode' के सदस्यों को समस्या से कोई लेना देना है? मुझे शक है। संक्षिप्त, स्वयं निहित, संकलन उदाहरण का पूरा बिंदु यह है कि आप वास्तव में कोड लिखते हैं जो * संकलित करता है और समस्या का प्रदर्शन करता है, और इसमें समस्या का प्रदर्शन करते समय भी इसे हटाया जा सकता है। आप इससे बेहतर कर सकते हैं। – Yakk

उत्तर

5

boost::bind() करने के लिए कॉल के संबंध में, आप boost::ref() का उपयोग जब एक समारोह टेम्पलेट है कि मूल्य द्वारा इसी तर्क को स्वीकार करता है के संदर्भ द्वारा एक वस्तु गुजर चाहिए, अन्यथा प्रतिलिपि का प्रयास किया जाएगा (जिसके परिणामस्वरूप एक प्रतिलिपि त्रुटि में है, क्योंकि कॉपी कन्स्ट्रक्टर पहुंच योग्य नहीं है):

boost::bind(TreeVisitor(), boost::ref(tree), val, keyIndex); 
//       ^^^^^^^^^^^^^^^^ 

हालांकि, यहां एक बड़ी समस्या है: boost::variant केवल प्रतिलिपि बनाने योग्य प्रकारों को पकड़ सकता है। Boost.Variant online documentation से:

एक घिरे प्रकार पर आवश्यकताओं इस प्रकार हैं:

  • CopyConstructible [20.1.3]।

  • विनाशक नो-थ्रो अपवाद-सुरक्षा गारंटी को बनाए रखता है।

  • संस्करण टेम्पलेट तत्कालता के बिंदु पर पूरा करें। variant करने के लिए (एक प्रकार का आवरण अधूरा प्रकार पुनरावर्ती भिन्न प्रकारों को सक्षम करने के लिए स्वीकार करता है कि boost::recursive_wrapper<T> देखें।)

हर प्रकार एक टेम्पलेट तर्क के रूप में निर्दिष्ट करना चाहिए कम से कम ऊपर दी गई आवश्यकताओं को पूरा। [...]

+0

मैंने 'पेड़' के चारों ओर लिपटे 'std :: ref' का उपयोग किया और संकलक ने 'त्रुटि C2558: कक्षा' बूस्ट :: _ bi :: list3 'जारी किया: कोई कॉपी कन्स्ट्रक्टर उपलब्ध नहीं है या कॉपी कन्स्ट्रक्टर को' स्पष्ट '' घोषित किया गया है ए 1 = बूस्ट :: _ द्वि :: मूल्य ए 2 = बूस्ट :: _ द्वि :: मूल्य , ए 3 = बूस्ट :: _ द्वि :: मूल्य Mushy

+0

@ मशी: फिर 'बूस्ट :: रेफरी' के बारे में कैसे ? यदि यह काम नहीं करता है, तो मैं इस उत्तर को हटा दूंगा –

+0

काम पर दिखाई देता है; कंपाइलर राज्यों 'त्रुटि सी 2248:' वृक्ष :: वृक्ष ':' वृक्ष 'वर्ग में घोषित निजी सदस्य तक नहीं पहुंच सकता है और' वृक्ष = स्ट्रिंग ट्री 'के साथ समस्या है जो मुझे लगता है कि' std :: move' की आवश्यकता हो सकती है। – Mushy

1
using Mixed = boost::variant< 
    std::unique_ptr<char>, 
    std::unique_ptr<short>, 
    std::unique_ptr<int>, 
    std::unique_ptr<unsigned long> 
>; 

int main() {  
    auto md = std::unique_ptr<int>(new int(123)); 
    Mixed mixed = std::move(md); 
    std::cout << *boost::get< std::unique_ptr<int> >(mixed) << std::endl; 
    return 0; 
} 

unique_ptr केवल के लिए कदम और संस्करण में इस्तेमाल किया जा सकता है। उपरोक्त उदाहरण संकलित और काम कर सकते हैं (सी ++ 11)।

संबंधित मुद्दे