2010-06-18 10 views
11

कृपया, देखें कि मैं क्या करने की कोशिश कर रहा हूं:टेम्पलेट विशेषज्ञता को अलग-अलग नामस्थानों में क्यों नहीं रखा जाता है?

#include <iostream> 
namespace first 
{ 
template <class T> 
class myclass 
{ 
    T t; 
public: 
    void who_are_you() const 
    { std::cout << "first::myclass"; } 
}; 
} 
namespace second 
{ 
using first::myclass; 
template <> 
class myclass <int> 
{ 
    int i, j; 
public: 
    void who_are_you() const 
    { std::cout << "second::myclass"; } 
}; 
} 

इसकी अनुमति नहीं है। क्या आप कृपया को स्पष्ट कर सकते हैं क्यों विशेषज्ञता नामांकन अलग-अलग नामस्थानों में नहीं हो सकता है, और उपलब्ध समाधान क्या हैं? साथ ही, क्या यह सी ++ 0x में कुछ तय है?

यह std::max, std::swap, std::numeric_limits, आदि को विशेषज्ञता देने के लिए उदाहरण के लिए मुझे अनुमति देगा .. ::std:: में कुछ जोड़कर अपरिभाषित व्यवहार का उपयोग किए बिना?


@AndreyT यह है कि मैं इसे कैसे उपयोग करूंगा:

// my_integer is a class 
std::numeric_limits<my_integer>::max(); // specialized std::numeric_limits for my_integer 

क्या यह किया जा सकता है?

+0

एक विकल्प के रूप में, क्या आप एक नया टेम्पलेट नहीं बना सकते जो मानक से प्राप्त होता है? – Cogwheel

+4

प्रति §17.4.3.1/1: "कोई प्रोग्राम किसी भी मानक लाइब्रेरी टेम्पलेट के लिए नामस्थान std में टेम्पलेट विशेषज्ञता जोड़ सकता है। एक मानक लाइब्रेरी टेम्पलेट के इस तरह की विशेषज्ञता (पूर्ण या आंशिक) अपरिभाषित व्यवहार में परिणाम जब तक कि घोषणा उपयोगकर्ता पर निर्भर न हो - बाह्य संबंध का निर्धारित नाम और जब तक कि मूल मूल टेम्पलेट के लिए विशेषज्ञता मानक पुस्तकालय आवश्यकताओं को पूरा न करे। " इसलिए प्रतिबंध होने पर, आप सही परिस्थितियों में ':: std ::' में ऐसी विशेषज्ञता जोड़ सकते हैं। –

+0

@ जेरी कॉफिन मैंने सोचा कि कुछ भी जोड़ने से एक अपरिभाषित व्यवहार होगा! कृपया इन आवश्यकताओं को पूरा करने के तरीके को समझाते हुए एक उत्तर प्रदान करेंगे? – AraK

उत्तर

7

सी ++ 2003, §17.4.3.1/1: "एक प्रोग्राम किसी भी मानक लाइब्रेरी टेम्पलेट के लिए नामस्थान std के लिए टेम्पलेट विशेषज्ञता जोड़ सकता है। एक मानक लाइब्रेरी टेम्पलेट के इस तरह की विशेषज्ञता (पूर्ण या आंशिक) अपरिभाषित व्यवहार में परिणाम तब तक जब तक घोषणा बाहरी लिंकेज के उपयोगकर्ता द्वारा परिभाषित नाम पर निर्भर न हो और जब तक विशेषज्ञता मूल टेम्पलेट के लिए मानक पुस्तकालय आवश्यकताओं को पूरा करती है। "

इस तरह के रूप में, आप एक पुस्तकालय टेम्पलेट विशेषज्ञ करने की अनुमति है, और जब तक यह एक उपयोगकर्ता परिभाषित प्रकार पर निर्भर करता है और मूल टेम्पलेट की आवश्यकताओं को पूरा नाम स्थान std में अपनी विशेषज्ञता में कहें,।

आपके संपादित प्रश्न में आपके पास मौजूद कोड उपयोगकर्ता द्वारा परिभाषित नाम के लिए एक विशेषज्ञता प्रतीत होता है (संभवतः) बाहरी संबंध है, इसलिए आपको चीजों के उस हिस्से के साथ कोई समस्या नहीं होनी चाहिए।

यह केवल उस आवश्यकता को छोड़ देता है जो आपकी विशेषज्ञता मूल टेम्पलेट की आवश्यकताओं को पूरा करती है। आपके प्रकार के लिए, इनमें से अधिकतर शायद छोटी सी सीमा पर सीमा होगी। एकमात्र भाग जो मैं देख सकता हूं वह स्पष्ट नहीं हो सकता है कि आपको पूरे टेम्पलेट के लिए विशेषज्ञता प्रदान करना प्रतीत होता है, न केवल numeric_limits::max()। यानी, आप की तरह (उदाहरण के एक 128-बिट अहस्ताक्षरित पूर्णांक प्रकार के लिए बॉलपार्क में होना चाहिए) कुछ करना होगा:

namespace std { 
template <> 
class numeric_limits<my_integer> { 
public: 

    static const bool is_specialized = true; 
    static T min() throw() { return 0; 
    static T max() throw() { return /* 2^128-1 */; } // *** 
    static const int digits = 128; 
    static const int digits10 = 38; 
    static const bool is_signed = false; 
    static const bool is_integer = true; 
    static const bool is_exact = true; 
    static const int radix = 2; 
    static T epsilon() throw() { return 0; } 
    static T round_error() throw() { return 0; } 
    static const int min_exponent = 0; 
    static const int min_exponent10 = 0; 
    static const int max_exponent = 0; 
    static const int max_exponent10 = 0; 
    static const bool has_infinity = false; 
    static const bool has_quiet_NaN = false; 
    static const bool has_signaling_NaN = false; 
    static const float_denorm_style has_denorm = denorm_absent; 
    static const bool has_denorm_loss = false; 
    static T infinity() throw() { return 0; } 
    static T quiet_NaN() throw() { return 0; } 
    static T signaling_NaN() throw() { return 0; } 
    static T denorm_min() throw() { return 0; } 
    static const bool is_iec559 = false; 
    static const bool is_bounded = true; 
    static const bool is_modulo = true; 
    static const bool traps = false; 
    static const bool tinyness_before = false; 
    static const float_round_style round_style = round_toward_zero; 
}; 
} 

काफी एक उन लोगों में से कुछ एफपी प्रकार के लिए वास्तव में कर रहे हैं, और की आवश्यकता नहीं है एक पूर्णांक प्रकार के लिए सार्थक होना; मेरा मानना ​​है कि उन्हें अभी भी लागू करने की जरूरत है।

+0

उत्तर देने के लिए धन्यवाद। एक छोटे स्पष्टीकरण कृपया, बाहरी संबंध द्वारा क्या मतलब है। अगर मेरी लाइब्रेरी केवल एक शीर्षलेख है, तो व्यवहार अपरिभाषित है? – AraK

+2

नहीं - "बाहरी संबंध" का अर्थ है कि यह 'स्थैतिक' या अज्ञात नामस्थान में नहीं है। –

+0

ग्रेट। यह अब क्रिस्टल स्पष्ट है :) – AraK

-4

ऐसा प्रश्न क्यों उठता है? यह समझने के बिना कि इसका उत्तर देना भी मुश्किल है।

विशेषज्ञता मुख्य टेम्पलेट को संशोधित करती है। यह मुख्य टेम्पलेट से किसी भी तरह से "अलग करने योग्य" नहीं है। कुछ हद तक, एक उच्च स्तरीय अवधारणा के रूप में, यह अभी भी एक ही टेम्पलेट है (भले ही निचले स्तर पर इसे एक स्वतंत्र के रूप में परिभाषित किया गया हो)। इसलिए, स्पष्ट कारणों से, यह मुख्य टेम्पलेट के समान नामस्थान में है।

क्षमा करें, मैं सिर्फ एक बेहतर स्पष्टीकरण प्रदान नहीं कर सकता, क्योंकि मुझे समझ में नहीं आता कि ऐसा प्रश्न कैसे उत्पन्न हो सकता है।

बीटीडब्ल्यू, "अलग-अलग नामस्थान" से आपका क्या मतलब है? आप विशेषज्ञता को अलग-अलग नामस्थान का सदस्य बनना चाहते हैं? या आप स्रोत विशेषज्ञता में एक अलग नेमस्पेस में अपनी विशेषज्ञता को परिभाषित करना चाहते हैं, लेकिन फिर भी मूल नामस्थान का सदस्य बने रहें?

3

यह पेचीदा बातें:

namespace first 
{ 
    template <class T> class TArray; 
} 

namespace second 
{ 
    using first::TArray; 

    template <class U> class TArray < Node<U> >; 
    //       ^
    // Only there do you realize it's a specialization and not another template 
} 

मैं आपकी परेशानी समझता हूं, मैं अक्सर एक ही बात के लिए कामना की। यह निश्चित रूप से संभव लगता है और मैं निश्चित रूप से लॉजिकल ग्रुपिंग तर्क नहीं खरीदता हूं, हालांकि मुझे यह स्वीकार करना होगा कि इसे कंपाइलर लेखकों से और भी अधिक प्रयास की आवश्यकता होगी, और सी ++ को सही ढंग से पार्स करना काफी मुश्किल है क्योंकि यह खड़ा है।

टेम्पलेट्स थोड़ा सी में गंदा कर रहे हैं ++ यदि आप मेरी राय चाहते हैं, लेकिन तब यह अनुभव के लाभ के साथ और उपयोग :) के 20 साल भी देखा है के बाद कहने के लिए आसान है

+0

@Matthiew एम धन्यवाद। अच्छा उत्तर। – AraK

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

  • कोई संबंधित समस्या नहीं^_^