2011-01-01 10 views
10

शीर्षक बहुत आत्म व्याख्यात्मक है, लेकिन यहाँ एक सरल उदाहरण है:क्या हमारे पास टेम्पलेट तर्क के रूप में अज्ञात संरचना हो सकती है?

#include <cstdio> 

template <typename T> 
struct MyTemplate { 

    T member; 

    void printMemberSize() { 
     printf("%i\n", sizeof(T)); 
    } 

}; 

int main() { 

    MyTemplate<struct { int a; int b; }> t; // <-- compiler doesn't like this 

    t.printMemberSize(); 

    return 0; 

} 

संकलक की शिकायत जब मैं एक टेम्पलेट तर्क के रूप में एक गुमनाम struct उपयोग करने के लिए प्रयास करें। एक अलग, नामित संरचना परिभाषा के बिना इस तरह कुछ हासिल करने का सबसे अच्छा तरीका क्या है?

उत्तर

7

आप परिभाषित सी ++ 03 या यहाँ तक कि C++ 0x से एक टेम्पलेट तर्क के रूप में एक अनाम प्रकार की अनुमति नहीं है।

सबसे अच्छा आप इसे मुख्य करने के लिए एक struct नामित स्थानीय बनाने के लिए क्या कर सकते हैं

(C++ 0x)

1: आप में सी + टेम्पलेट तर्क के रूप में एक स्थानीय प्रकार का उपयोग करने की अनुमति नहीं है +03, हालांकि सी ++ 0x इसे अनुमति देता है।

दोष रिपोर्ट here भी देखें। प्रस्तावित समाधान का उल्लेख है

निम्नलिखित प्रकार एक टेम्पलेट प्रकार पैरामीटर के लिए एक टेम्पलेट तर्क के रूप में इस्तेमाल नहीं किया जाएगा:

  • एक प्रकार जिसका नाम कोई संबंध
  • एक अनाम वर्ग या है गणना प्रकार जिसका लिंकेज उद्देश्यों के लिए कोई नाम नहीं है (7.1.3 [डीसीएल।typedef])
  • इस सूची में किसी एक प्रकार की एक सीवी योग्य संस्करण
  • एक प्रकार इस सूची में प्रकारों में से एक के लिए declarator ऑपरेटरों के आवेदन के द्वारा बनाई गई
  • एक समारोह प्रकार से एक का उपयोग करता है इस सूची

संकलक में प्रकार की शिकायत है जब मैं एक टेम्पलेट पैरामीटर के रूप में एक गुमनाम struct उपयोग करने के लिए प्रयास करें।

क्या आपका टेम्पलेट तर्क था? टेम्पलेट पैरामीटर टेम्पलेट तर्क से अलग है।

उदाहरण

लिए

template < typename T > // T is template parameter 
class demo {}; 

int main() 
{ 
    demo <int> x; // int is template argument 
} 
+0

सी ++ 0x में, एक अज्ञात प्रकार की वस्तु को टेम्पलेट तर्क के रूप में घटाया जा सकता है, लेकिन मुझे नहीं लगता एक अज्ञात प्रकार टेम्पलेट तर्क सूची में स्पष्ट रूप से निर्दिष्ट किया जा सकता है। –

+0

प्रसून, क्या आप मुझे मानक के सही खंड में संदर्भित कर सकते हैं? एक अज्ञात संरचना के साथ मेरा टेस्ट केस (टाइपिफ़ को पास किया गया है, लेकिन हम सभी जानते हैं कि टाइपिफ़ नाम एक संरचना नाम नहीं है) बस ठीक है। –

+0

@ बेन: '14.3.1/2' –

4

आपकी समस्या यह नहीं है कि संरचना का नाम बदल दिया गया है, यह है कि संरचना स्थानीय रूप से घोषित की जाती है। सी ++ 03 में टेम्पलेट तर्कों के रूप में स्थानीय प्रकारों का उपयोग करने की अनुमति नहीं है। यह हालांकि C++ 0x में होगा, इसलिए आप अपने कंपाइलर को अपग्रेड करने का प्रयास कर सकते हैं।

संपादित करें: असल में, आपकी समस्या यह है कि एक टेम्पलेट तर्क सूची के अंदर सी ++ मानक के अनुसार, नाम के साथ या बिना किसी वर्ग परिभाषा को रखने के लिए कानूनी जगह नहीं है।

litb बताते हैं कि हालांकि यह C++ 0x व्याकरण में फिट बैठता है, एक प्रकार यहाँ [dcl.type] द्वारा निषिद्ध है परिभाषित करने:

एक प्रकार-विशिष्ट एर-सेक करेगा नहीं डी फाई ne कक्षा या गणन जब तक यह प्रकट होता है उपनाम-घोषणा (7.1.3) के प्रकार-आईडी में जो टेम्पलेट-घोषणा की घोषणा नहीं है।

simple-template-id: 
    template-name < template-argument-list_opt > 

template-argument-list: 
    template-argument ..._opt 
    template-argument-list , template-argument ..._opt 

template-argument: 
    constant-expression 
    type-id 
    id-expression 

type-id: 
    type-specifier-seq abstract-declarator_opt 

type-specifier-seq: 
    type-specifier attribute-specifier-seq_opt 
    type-specifier type-specifier-seq 

type-specifier: 
    trailing-type-specifier 
    class-specifier 
    enum-specifier 

class-specifier: 
    class-head { member-specification_opt } 

थोड़ी देर के लिए मैं typedef नामों के बारे में एक सवाल था, लेकिन litb को मंजूरी दे दी है कि। वे के माध्यम से टेम्पलेट तर्क के रूप में अनुमति दी जाती है:

trailing-type-specifier: 
    simple-type-specifier 
    elaborated-type-specifier 
    typename-specifier 
    cv-qualifier 

simple-type-specifier: 
    :: opt nested-name-specifier_opt type-name 
    :: opt nested-name-specifier template simple-template-id 
    char 
    char16_t 
    char32_t 
    wchar_t 
    bool 
    short 
    int 
    long 
    signed 
    unsigned 
    float 
    double 
    void 
    auto 
    decltype-specifier 

type-name: 
    class-name 
    enum-name 
    typedef-name 
    simple-template-id 
+0

असल में मैं जीसीसी 4.5 के C++ 0x क्षमताओं का उपयोग कर रहा हूँ। क्या यह सुविधा अभी तक लागू नहीं की जा रही है? – nonoitall

+0

@nonoitall: [सी ++ 0x टैग विकी] (http://stackoverflow.com/tags/c%2b%2b0x/info) कई कंपाइलर्स में सी ++ 0x समर्थन की स्थिति पर बहुत सारी जानकारी के लिंक हैं । यह कहता है कि इसे जीसीसी 4.5 में जोड़ा जाना चाहिए। [आधिकारिक जीसीसी रिलीज नोट्स] (http://gcc.gnu.org/gcc-4.5/changes.html) "सी ++ 0x मोड में स्थानीय और अज्ञात वर्गों को अब टेम्पलेट तर्क के रूप में अनुमति दी जाती है"। आप '-std = gnu ++ 0x' विकल्प के साथ संकलित कर रहे हैं, है ना? –

+0

मेरा बुरा। जाहिर है यह कुछ ऐसा है जो जीसीसी 4.5 के मिनजीडब्ल्यू बंदरगाह पर पीछे छोड़ दिया गया है। इसे एक लिनक्स बॉक्स पर संकलित करने का प्रयास किया गया और यह स्थानीय रूप से परिभाषित संरचना का उपयोग करते समय संकलित होगा (हालांकि एक अज्ञात संरचना का प्रयोग तर्क के रूप में अभी भी उड़ नहीं जाएगा)।/मैं सिगविन स्थापित करने के लिए चला जाता है। – nonoitall

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