2013-08-24 3 views
5

यह भिन्नता वाले टेम्पलेट्स के साथ एक सामान्य स्थिति होनी चाहिए उदाहरण के लिए जब पेड़ चलने वाले बच्चों को विविध टेम्पलेट तर्क होते हैं। मुझे कई संबंधित प्रश्न और उत्तर मिलते हैं लेकिन या तो वे थोड़ा अलग चीज हैं या वे एक ही चीज़ हैं और मुझे यह नहीं मिला। अब समस्या के लिए। मैं इसफ़ंक्शन ओवरलोड के भिन्नता टेम्पलेट तर्कों का उपयोग करते समय मेल खाने वाला संदिग्ध टेम्पलेट पैटर्न

template <class E, class T1, class T2, class T3, etc...> 
struct X; 

की तरह एक गैर variadic टपल है और मैं कार्यों ओवरलोडिंग कर रहा हूँ इस तरह के टपल सूचक प्रकार या वेक्टर सूचक प्रकार किया जा रहा है के पहले तत्व के आधार पर विशेष व्यवहार है। यह ठीक काम करता है लेकिन यदि मैं टेम्पलेट तर्कों को एक भिन्न चरम टेम्पलेट तर्क में पैक करता हूं, तो अधिभार अस्पष्ट हो जाते हैं।

variadic.cpp:42:17: error: ambiguous overload for ‘operator<<’ in ‘std::cout << y’ 
variadic.cpp:42:17: note: candidates are:... 

संकलक X<H*,T*...> से अधिक X<vector<V*>*,T*...> को प्राथमिकता देनी चाहिए जब यह टपल के पहले तत्व के रूप में vector<double*>* मिलान करने के लिए कोशिश करता है: त्रुटि संदेश यह।

मैं enable_if का उपयोग करके असंबद्ध कर सकता हूं और चीजें फिर से काम कर सकती हैं। हालांकि मैं त्रुटि को समझना चाहता हूं और यदि संभव हो तो अन्य साधनों को ढूंढें तो enable_if।

#include <iostream> 
#include <vector> 
#include <boost/type_traits/is_fundamental.hpp> 
#include <boost/utility/enable_if.hpp> 

using namespace std; 

template <typename ... T> 
struct X; 

template <> 
struct X <> 
{ 
}; 

template <typename H, typename ... T> 
struct X<H*,T*...> : public X<T*...> 
{ 
     H* value; 
     X(H* value, T*... args) 
       : value(value), X<T*...>(args...) 
     { 
     } 
}; 

template <typename H, typename ... T> 
#ifdef DO_NOT_WANNA_SEE_THE_BUG 
typename boost::enable_if<boost::is_fundamental<H>, std::ostream>::type& 
     operator<<(std::ostream& stream, X<H*,T*...> const & x) 
#else 
std::ostream& operator<<(std::ostream& stream, X<H*,T*...> const & x) 
#endif 
{ 
     return stream << "specialized scalar pointer"; 
} 

template <typename V, typename ... T> 
std::ostream& operator<<(std::ostream& stream, X<vector<V*>*,T*...> const & x) 
{ 
     return stream << "specialized vector pointer"; 
} 

int main() 
{ 
     double a,b; 
     vector<double *> v; 
     X<double*,double*> x (&a,&b); 
     X<vector<double*>*, double*> y (&v, &b); 
     cout << x << endl; 
     cout << y << endl; // this line is ambiguous according to gcc 4.6 and later 
} 
+3

यह नहीं कि यह बिल्कुल मदद करता है, लेकिन ऐप्पल एलएलवीएम 4.2 (क्लैंग) बिना किसी समस्या के इसे ठीक करता है। मुझे यह जानकर उत्सुकता है कि क्या जीसीसी के पास भिन्नता के बिना एक ही समस्या है 'टी * ...' (जो मैं देखता हूं उससे आवश्यक नहीं है), और इसके बजाय आपने 'टी ...' का उपयोग किया। यह कोई फर्क नहीं पड़ता कि इससे कोई फर्क क्यों पड़ता है, लेकिन फिर, जीसीसी पुकिंग कर रहा है, और क्लैंग ऐसा नहीं है ... [इसे ideone.com पर लाइव देखें] (http://ideone.com/ja1ZSb) – WhozCraig

+1

अनुवर्ती: I सिर्फ देखा गया ideone.com जीसीसी 4.8 का उपयोग करता है, बस fyi। – WhozCraig

+0

@WozozCraig। सही जवाब तुम सही हो। मैं सब कुछ पॉइंटर्स को प्रतिबंधित करना चाहता था लेकिन निश्चित रूप से यह सिर के लिए ऐसा करने के लिए पर्याप्त है। पैक की पूंछ के लिए इसकी आवश्यकता नहीं है। आपका सुझाव पुराने जीसीसी 4.6 के लिए भी काम करता है। एलएलवीएम पर आपकी टिप्पणी भी बहुत दिलचस्प है। बहुत धन्यवाद! –

उत्तर

0

सार WhozCraig की टिप्पणी से है:

जब आप टी * ड्रॉप दोनों कार्यक्रम (चेतावनी -Wreorder के साथ) संकलन होगा टेम्पलेट्स में और देना उम्मीद यहाँ कोड है उत्पादन।

operator<<(std::ostream& stream, X<H*,T...> const & x) 
operator<<(std::ostream& stream, X<vector<V*>*, T...> const & x) 

बिना किसी ज्ञान के [14] टेम्पलेट्स के माध्यम से जाने के बाद, मुझे लगता है कि एक कंपाइलर बग है।

एक संशोधित टेस्ट:

#include <iostream> 
#include <vector> 
#include <boost/type_traits/is_fundamental.hpp> 
#include <boost/utility/enable_if.hpp> 

using namespace std; 

#define USE_VARIADIC_TEMPLATE 1 
#define USE_AMBIGUOUS 1 

template <typename ... T> 
struct X; 

template <> 
struct X <> 
{ 
}; 

template <typename H, typename ... T> 
struct X<H*,T*...> : public X<T*...> 
{ 
    H* value; 
    X(H* value, T*... args) 
    : X<T*...>(args...), value(value) 
    {} 
}; 

#if USE_VARIADIC_TEMPLATE 
template <typename H, typename ... T> 
#if USE_AMBIGUOUS 
std::ostream& operator<<(std::ostream& stream, X<H*,T*...> const & x) 
#else 
std::ostream& operator<<(std::ostream& stream, X<H*,T...> const & x) 
#endif 
#else 
template <typename H, typename T> 
std::ostream& operator<<(std::ostream& stream, X<H*, T*> const & x) 
#endif 
{ 
     return stream << "specialized scalar pointer"; 
} 

#if USE_VARIADIC_TEMPLATE 
template <typename V, typename ... T> 
#if USE_AMBIGUOUS 
std::ostream& operator<<(std::ostream& stream, X<vector<V*>*,T*...> const & x) 
#else 
std::ostream& operator<<(std::ostream& stream, X<vector<V*>*,T...> const & x) 
#endif 
#else 
template <typename V, typename T> 
std::ostream& operator<<(std::ostream& stream, X<vector<V*>*, T*> const & x) 
#endif 
{ 
     return stream << "specialized vector pointer"; 
} 

int main() 
{ 
     double a,b; 
     vector<double *> v; 
     X<double*,double*> x (&a,&b); 
     X<vector<double*>*, double*> y (&v, &b); 
     cout << x << endl; 
     cout << y << endl; // this line is ambiguous according to gcc 4.6 and later 
} 

यहां तक ​​कि मामला:

template <typename H, typename T> 
std::ostream& operator<<(std::ostream& stream, X<H*, T*> const & x) 
template <typename V, typename T> 
std::ostream& operator<<(std::ostream& stream, X<vector<V*>*, T*> const & x) 

अच्छी तरह से संकलित करता है।

संपादित: तो variadic टेम्पलेट पकड़ सिर्फ एक टी टी के रूप में पारित * यह आसान मामला ऊपर दिखाया जाना चाहिए।

+0

मैं WhozCraig से संशोधन पसंद करता हूं क्योंकि सभी टी * को शामिल किया जा सकता है ... अनपॅकिंग को हटाया जाना चाहिए और न केवल फ़ंक्शन ओवरलोड टेम्पलेट्स के। आपके संशोधित कोड में आपको अंतिम टिप्पणी भी हटा दी जानी चाहिए क्योंकि यह उस संदर्भ में भ्रमित है। –

+0

... मैं अब सहमत हूं कि यहां एक कंपाइलर त्रुटि है लेकिन गंभीर नहीं है क्योंकि यह वैसे भी एक चेतावनी होनी चाहिए।सही जवाब यह है कि आप और पहले WhozCraig ने बताया कि मैंने कुछ बेवकूफ लिखा था और धन्यवाद, इसलिए अब मुझे पता है। –

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

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