2009-12-14 29 views
7

मेरे पास एक टेम्पलेटेड क्लास ए < टी, इंट> और दो टाइपपीफ ए < स्ट्रिंग, 20> और ए < स्ट्रिंग, 30> है। मैं < स्ट्रिंग, 20> के लिए कन्स्ट्रक्टर को ओवरराइड कैसे करूं? निम्नलिखित काम नहीं करता:सी ++ कन्स्ट्रक्टर का सी ++ टेम्पलेट विशेषज्ञता

template <typename T, int M> class A; 
typedef A<std::string, 20> one_type; 
typedef A<std::string, 30> second_type; 


template <typename T, int M> 
class A { 
public: 
    A(int m) {test= (m>M);} 

    bool test; 

}; 


template<> 
one_type::one_type() { cerr << "One type" << endl;} 

मैं कुछ है कि अन्य वर्ग नहीं है ऐसा करने के लिए वर्ग एक < std :: स्ट्रिंग, 20> चाहते हैं। मैं कन्स्ट्रक्टर ए: ए (int) को बदले बिना ऐसा कैसे कर सकता हूं?

+0

आप कक्षाएं करने के लिए प्राप्त करने के लिए कोशिश कर रहे हैं? – GManNickG

+0

सवाल अस्पष्ट है। बीटीडब्ल्यू, एक_ प्रकार के पास कोई खाली कन्स्ट्रक्टर नहीं है, इसमें int पैरामीटर के साथ कन्स्ट्रक्टर है। – Drakosha

उत्तर

1

आप अपने वर्तमान दृष्टिकोण के साथ नहीं कर सकते हैं। one_type एक विशेष टेम्पलेट विशेषज्ञता के लिए उपनाम है, इसलिए यह टेम्पलेट के पास जो भी कोड प्राप्त करता है।

आप one_type के लिए विशिष्ट कोड जोड़ना चाहते हैं, तो आप, एक विशेषज्ञता का एक उपवर्ग के रूप में यह घोषणा करने के लिए है इस तरह:

class one_type: 
    public A<std::string>, 20> 
    { 
    one_type(int m) 
     : A<str::string, 20>(m) 
    { 
     cerr << "One type" << endl; 
    } 
    }; 
+0

ऐसा सोचा। कन्स्ट्रक्टर को सदस्य कार्यों के रूप में विशिष्ट नहीं किया जा सकता है, क्या आप एक तर्क प्रदान कर सकते हैं क्यों नहीं? –

+0

नीचे उत्तर दिया गया: –

6

मानते हुए अपने वास्तव मेंA::test के लिए सार्वजनिक रूप से सुलभ होने के लिए आपको

#include <iostream> 


template <int M> 
struct ABase 
{ 
    ABase(int n) : test_(n > M) 
    {} 

    bool const test_; 
}; 


template <typename T, int M> 
struct A : ABase<M> 
{ 
    A(int n) : ABase<M>(n) 
    {} 
}; 


template <typename T> 
A<T, 20>::A(int n) 
    : ABase<20>(n) 
    { std::cerr << "One type" << std::endl; } 

किक टायर:

int main(int argc, char* argv[]) 
{ 
    A<int, 20> a(19); 
    std::cout << "a:" << a.test_ << std::endl; 
    A<int, 30> b(31); 
    std::cout << "b:" << b.test_ << std::endl; 
    return 0; 
} 
कुछ इस तरह कर सकता है
+1

अच्छा जवाब, प्रकार सिस्टम के साथ पागल जा रहा है: पी –

8

एकमात्र चीज जो आप नहीं कर सकते हैं वह typedef का उपयोग कन्स्ट्रक्टर को परिभाषित करने के लिए करता है।

template<> class A<string,20> { 
public: 
    A(const string& takethistwentytimes) { cerr << "One Type" << std::endl; } 
}; 
:

template<> A<string,20>::A(int){} 

आप चाहते हैं A<string,20> सामान्य A की तुलना में एक अलग निर्माता है करने के लिए हैं, तो आप पूरे A<string,20> वर्ग विशेषज्ञ की जरूरत है: उसके अलावा, आप A<string,20> निर्माता इस तरह के विशेषज्ञ चाहिए

0

कैसे के बारे में:

template<typename T, int M, bool dummy = (M > 20) > 
class A { 
public: 
    A(int m){ 
     // this is true 
    } 

}; 

template<typename T, int M> 
class A<T,M,false> { 
public: 
    A(int m) { 
    //something else 
    } 
}; 
0

सबसे अच्छा समाधान मैं के लिए इस स्थिति को एक "निर्माता सहायक समारोह" का उपयोग करने के लिए है के साथ आने कर लिया है:

template <typename T, int M> class A; 
typedef A<std::string, 20> one_type; 
typedef A<std::string, 30> second_type; 

template <typename T, int M> 
class A { 
private: 
    void cons_helper(int m) {test= (m>M);} 
public: 
    A(int m) { cons_helper(m); } 

    bool test; 
}; 

template <> 
void one_type::cons_helper(int) { cerr << "One type" << endl;} 
0

यह एक छोटा सा देर से हो सकता है, लेकिन आप के लिए SFINAE उपयोग कर सकते हैं आप c++11 के लिए उपयोग किया है, तो बस पूरा आप क्या चाहते हैं:

template <class = typename std::enable_if< 
    std::is_same<A<T,M>, A<std::string, 20>>::value>::type // Can be called only on A<std::string, 20> 
    > 
    A() { 
    // Default constructor 
    } 

Working example

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