7

संकलित नहीं करते हैं, मैं बूस्ट के साथ सी ++ में काफी नया हूं।डायनेमिकली आवंटित बूस्ट मल्टी_एरे में कक्षा में पॉइंटर्स,

मुझे कक्षा "दुनिया" का एक उद्देश्य "ऑक्टीरोडोड" प्रकार के "खंड" नामक एक सरणी चाहिए। पहले मेरे पास एक सामान्य आयामी सरणी थी, और यह ठीक काम करता था। अब मैं बूस्ट की मल्टी_एरे कार्यक्षमता के साथ एक 3 डी सरणी का उपयोग करने की कोशिश कर रहा हूं, और मुझे सच में यकीन नहीं है कि मैं क्या गलत कर रहा हूं।

सरलीकृत कोड:

class world { 
public: 

    typedef boost::multi_array<octreenode, 3> planetchunkarray; // a boost_multi for chunks 
    typedef planetchunkarray::index index; 
    planetchunkarray *chunk; 

    world(double x,double y,double z, 
     int widtheast, int widthnorth, int height) : 
     originx(x), originy(y), originz(z), 
     chunkseast(widtheast), chunksnorth(widthnorth), chunksup(height) { 

    chunk = new planetchunkarray(boost::extents[chunksnorth][chunkseast][chunksup]); 
    planetchunkarray::extent_gen extents; 

    for (int cz = 0; cz < chunksnorth; ++cz) { 
     for (int cx = 0; cx < chunkseast; ++cx) { 
     for (int cy = 0; cy < chunksup; ++cy) { 
      (*chunk)[cz][cx][cy] = new octreenode(1,72); 
     } 
     } 
    } 
    } 
}; 

इसके बाद अगर मैं काम

root->planet[0]->chunk[0][0][0]->material = 4;

मैं त्रुटि मिलती है करने का प्रयास:

error: base operand of '->' has non-pointer type 'boost::detail::multi_array::sub_array<octreenode, 1u>'| 

"octreenode" प्रासंगिक निर्माता है, और यह लाइन समान वाक्यविन्यास में काम करती थी जब यह केवल था:

root->planet[0]->chunk[0]->material = 4;

(एक-आयामी सरणी के साथ)। इसी प्रकार, जबकि यह एक आयामी सरणी के साथ ठीक संकलित, काम करता है, इस तरह के रूप कि एक "octreenode" वस्तु के लिए सूचक की उम्मीद हिस्सा पारित करने के लिए कोशिश कर रहा है:

compactoctree(root->planet[p]->chunk[cz][cx][cy], 0, 14);

त्रुटि

error: cannot convert 'boost::detail::multi_array::sub_array<octreenode, 1u>' to 'octreenode*' for argument '1' to 'short int compactoctree(octreenode*, int, int)'| 
उत्पन्न करता है

किसी भी सुझाव के लिए बहुत आभारी होंगे, मुझे यकीन है कि मुझे कुछ स्पष्ट याद आ रहा है।

+0

(अपसंदर्भन "हिस्सा" के सुझाव विशेष रूप से https से आया है के निर्माण के लिए निर्माता प्रारंभ सूची का उपयोग कर सकते हैं: // समूहों .google.com/forum/?ggroups = #! विषय/बूस्ट-सूची/IWKIdlrg4dU) – Riot

उत्तर

4

आपका सरणी मान प्रकार (octreenode), प्रकार (octreenode*)

इसलिए यदि आप एक गतिशील आवंटित octreenode के लिए सूचक आवंटित करने के लिए प्रयास करने के लिए नहीं जा सकते सूचक नहीं (new ढेर आवंटन के लिए है, डिफ़ॉल्ट रूप से) का है ।

 (*chunk)[cz][cx][cy] = octreenode(1,72); 

वास्तव में, वहाँ पहली जगह या तो में बहु सरणी पर new उपयोग करने के लिए कोई कारण नहीं है:

इसके बजाय, बस एक मूल्य निर्दिष्ट

अद्यतन

टिप्पणियों में यह उठाया गया है कि अधिक चीजों को अनुकूलित किया जा सकता है और आप संकलन त्रुटि के बारे में उत्तर में उपयोगी जोड़ों पर विचार करते हैं।

तो यहाँ है: यदि आप वास्तव में ठीक उसी मूल्य के साथ सभी सरणी तत्वों को प्रारंभ करना चाहते हैं,

  1. आप एक पल के लिए सरणी आकार के बारे में भूल से छोरों तरह से और अधिक कुशल बनाने कर सकते हैं:

    std::fill_n(chunk.data(), chunk.num_elements(), octreenode {1, 72}); 
    

    यदि आप जानते हैं octreenode एक पॉड प्रकार है, आप लिख सकता है

    std::uninitialzed_fill_n(chunk.data(), chunk.num_elements(), octreenode {1, 72}); 
    

    लेकिन एक स्मार्ट लाइब्रेरी कार्यान्वयन किसी भी तरह से fill_n पर कॉल करना समाप्त कर देगा (क्योंकि कोई लाभ नहीं है)। uninitialized_fill_n का उपयोग कर सकते हैं यदि octreenode एक पीओडी प्रकार नहीं है, लेकिन यह मामूली विनाशकारी है।

  2. वास्तव में, पहले स्थान पर बहु ​​सरणी पर नया उपयोग करने का कोई कारण नहीं है। तुम बस multi_array सदस्य


Live On Coliru

#include <boost/multi_array.hpp> 
#include <type_traits> 

struct octreenode { int a; int b; }; 

class world { 
public: 
    world(double x, double y, double z, int widtheast, int widthnorth, int height) 
      : 
       originx(x), originy(y), originz(z), 
       chunkseast(widtheast), chunksnorth(widthnorth), chunksup(height), 
       chunk(boost::extents[chunksnorth][chunkseast][chunksup]) 
    { 
     octreenode v = { 1, 72 }; 
     std::fill_n(chunk.data(), chunk.num_elements(), v); 
    } 

private: 
    double originx, originy, originz; 
    int chunkseast, chunksnorth, chunksup; 

    typedef boost::multi_array<octreenode, 3> planetchunkarray; // a boost_multi for chunks 
    typedef planetchunkarray::index index; 
    planetchunkarray chunk; 
}; 

int main() { 
    world w(1,2,3,4,5,6); 
} 
+0

चूंकि मैंने कुछ साल पहले यह पूछा था कि संदर्भ को याद रखना थोड़ा मुश्किल है, लेकिन बहु सरणी घोषित किया जा रहा है ढेर पर लाल क्योंकि यह ढेर के लिए बहुत बड़ा था; मेमोरी में समवर्ती भाग रखने की इच्छा ही पॉइंटर्स की एक सरणी के बजाय ढेर पर गैर-पॉइंटर्स के बहु-सरणी आवंटित करने के इरादे से थी, जो पूरे स्थान पर हो सकती थीं, और ड्रेफरेंसिंग और पुनरावृत्ति के दौरान कैश को तोड़ देती थीं। हालांकि, मैं अब देख रहा हूं कि इस तरह से "नया ऑक्टेट्रीनोड" का मेरा प्रयास गलत तरीके से खोला गया था, और मुझे नए प्लेसमेंट फॉर्म का उपयोग करना चाहिए था। मैं एक उत्तर पोस्ट करूंगा। – Riot

+0

एमएमएम। मुझे लगता है कि यह मुझे "अनुत्तरित" कतार से दूर रहने के लिए सिखाता है ... – sehe

+2

मुझे उम्मीद नहीं है! आपके उत्तर ने मुझे इस पर फिर से विचार करने के लिए प्रेरित किया, और उम्मीद है कि यह चर्चा भविष्य में Google से आने वाले किसी व्यक्ति के लिए उपयोग की जाएगी। – Riot

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