2011-02-05 5 views
7

वहाँ अंतर्निहित मानकों के साथ टेम्पलेट वर्ग की एक घोषणा है :टेम्पलेट्स, सी ++

Analysis.h

template <typename T, const bool attribute = true> 
class List; 

लेकिन जी ++ इस त्रुटि दिखाता है:

List.h:28: error: redefinition of default argument for `bool attribute' 
Analysis.h:43: error: original definition appeared here 

अगर मैं अंतर्निहित पैरामीटर के बिना आगे घोषणा का उपयोग

template <typename T, const bool attribute> 
class List; 

संकलक इस निर्माण

Analysis.h

void function (List <Object> *list) 
{ 
} 

स्वीकार करते हैं और निम्न त्रुटि से पता चलता नहीं है (अर्थात अंतर्निहित मूल्य स्वीकार नहीं करता है):

Analysis.h:55: error: wrong number of template arguments (1, should be 2) 
Analysis.h:44: error: provided for `template<class T, bool destructable> struct List' 
Analysis.h:55: error: ISO C++ forbids declaration of `list' with no type 

अपडेट किया गया प्रश्न:

मैं टेम्पलेट परिभाषा से डिफ़ॉल्ट पैरामीटर हटाया:

List.h

template <typename Item, const bool attribute> 
class List: public OList <item, attribute> 
{ 
    public: 
    List() : OList<Item, attribute>() {} 
    .... 
}; 

पहले कक्षा सूची का उपयोग कर फ़ाइल में पैरामीटर विशेषता

के निहित मूल्य के साथ आगे की घोषणा है

Analysis1.h

template <typename T, const bool attribute = true> 
class List; //OK 

class Analysis1 
{ 
    void function(List <Object> *list); //OK 
}; 

दूसरा आगे परिभाषा के साथ कक्षा सूची का उपयोग कर निहित मूल्य

का उपयोग कर Analysis2.h

template <typename T, const bool attribute = true> // Redefinition of default argument for `bool attribute' 
class List; 

class Analysis2 
{ 
    void function(List <Object> *list); //OK 
}; 

द्वितीय श्रेणी आगे परिभाषा का उपयोग किए बिना वर्ग सूची का उपयोग कर वर्ग निहित मूल्य

विश्लेषण 2.h

template <typename T, const bool attribute> // OK 
class List; 

class Analysis2 
{ 
    void function(List <Object> *list); //Wrong number of template arguments (1, should be 2) 
}; 
+0

ठीक है मैं आपकी समस्या को समझ में हो जाता है। ऐसा इसलिए है क्योंकि आप प्रत्येक फ़ाइल में आगे की घोषणा जोड़ते हैं जहां आप * 'सूची 'का उपयोग करते हैं। ऐसा मत करो। इसके बजाय 'List.h' में आगे की घोषणा जोड़ें, जहां आप' सूची '** और **' # शामिल करें "List.h" को परिभाषित करते हैं, जहां आप 'सूची' का उपयोग करते हैं। अगर आपको अभी भी समस्या का सामना करना पड़ता है तो मुझे बताएं! – Nawaz

+0

तो अपडेट के बाद आपका प्रश्न क्या है? – UmmaGumma

उत्तर

5

सरल।परिभाषा से डिफ़ॉल्ट मान हटाएं, क्योंकि आपने पहले ही घोषणा की है कि आगे की घोषणा में।

template <typename Item, const bool attribute = true> //<--- remove this 'true` 
class List: public OList <item, attribute> 
{ 
    //.. 
}; 

लिखें:

template <typename Item, const bool attribute> //<--- this is correct! 
class List: public OList <item, attribute> 
{ 
    //.. 
}; 

ऑनलाइन डेमो: http://www.ideone.com/oj0jK

+1

धन्यवाद, यह काम करता है :-)। – Robo

+0

@ रोबो: अगर यह काम करता है, तो टिक मार्क पर क्लिक करके इस जवाब को "स्वीकार करें"। अब तक आपने एक भी जवाब स्वीकार नहीं किया है! – Nawaz

+0

@ नवाज: मैं आगे की घोषणा के बजाय घोषणा में डिफ़ॉल्ट मान डालना चाहता हूं। मुझे लगता है कि यह इस तरह से भी स्पष्ट है। – jopasserat

0

आप केवल एक ही स्थान (किसी दिए गए अनुवाद के लिए) में डिफ़ॉल्ट पैरामीटर को परिभाषित कर सकते हैं। कक्षा घोषणा में ऐसा करने के लिए सबसे उपयोगी है, और इसे आगे बढ़ाने के लिए एक बुरा विचार है।

आगे एक डिफ़ॉल्ट पैरामीटर की आवश्यकता नहीं है (आपको इसे कुछ मामलों में टाइप करना होगा)।

आप एक और सरल टेम्पलेट प्रकार बना सकते हैं जो इसे आगे के संयोजन के साथ लागू करता है, यदि आप वास्तव में एक डिफ़ॉल्ट पैरामीटर चाहते हैं। तो आप एक टाइपपीफ के माध्यम से परिणाम का उपयोग करें। आप सूची के आगे का उपयोग कर ऐसा कर सकते हैं।

0

आपको यह सुनिश्चित करना केवल पहले घोषणा पैरामीटर का डिफ़ॉल्ट मान है बनाना चाहिए। इसे पहले एक फॉरवर्ड-घोषणा-केवल शीर्षलेख को परिभाषित करके पूरा किया जा सकता है, फिर इसे List.h और Analysis.h दोनों से भी शामिल किया जा सकता है। List.h में परिभाषा में, डिफ़ॉल्ट मान शामिल न करें।

0

आपको प्रत्येक फ़ाइल में List.h शामिल करना होगा, जहां आप इसका उपयोग कर रहे हैं। घोषणापत्र केवल नॉनटेम्प्लेट प्रकारों के लिए ही विचार किया जाता है। टेम्पलेट प्रकारों के लिए आपको प्रत्येक संकलन इकाई के लिए हेडर फ़ाइल शामिल करनी होगी।

+0

लेकिन इस मॉडल का उपयोग कर हेडर फ़ाइलों में परिपत्र लचीलापन से कैसे बचें? – Robo

+0

@Robo मैं नहीं कहता, कि आप इसे घोषित नहीं कर सकते, मैं कहता हूं कि आपको हेडर फ़ाइल शामिल करनी होगी। निर्भरताओं को हल करने के लिए आपको संभवतः हेडर समेत कक्षाओं की घोषणा करनी होगी। लेकिन आप अपने उत्तर के लिए हेडर – UmmaGumma

+0

धन्यवाद शामिल करने की आवश्यकता चोरी करते हैं, मैंने अपना प्रश्न अपडेट किया है ... – Robo

2

सम्भावित समाधान, List_fwd.h

template <typename Item, const bool attribute> 
class List; 

तो दोनों List.h और Analysis.h में आप शुरुआत में List_fwd.h शामिल एक अन्य हेडर फाइल घोषित करने के लिए है। तो List.h

#include "List_fwd.h" 

template <typename Item, const bool attribute = true> 
class List: public OList <item, attribute> 
{ 
    public: 
    List() : OList<Item, attribute>() {} 
    ... 
}; 

और Analysis.h

#include "List_fwd.h"