एक टेम्पलेट परिभाषा टेम्पलेट परिभाषा से मेल खाती है? मुझे मानक में कुछ पाठ टेम्पलेट-आईडी एक ही फ़ंक्शन का जिक्र करते हैं, यदि "उनके टेम्पलेट-नाम [...] उसी टेम्पलेट का संदर्भ लें और [...]" (14.4 [temp.type] पी 1) लेकिन मुझे टेम्पलेट-नाम या टेम्पलेट-नाम के लिए एक ही टेम्पलेट का संदर्भ नहीं मिल सकता है। मुझे यकीन नहीं है कि मैं सही रास्ते पर हूं या नहीं, क्योंकि मैंने व्याकरण को पर्याप्त रूप से नहीं बताया है कि टेम्पलेट-आईडी किसी टेम्पलेट की परिभाषा/घोषणा का हिस्सा है, या केवल एक का उपयोग है टेम्पलेट।टेम्पलेट घोषणाओं से टेम्पलेट परिभाषाएं कैसे मेल खाती हैं?
उदाहरण के लिए, निम्न प्रोग्राम ठीक काम करता है।
#include <iostream>
template<typename T>
T foo(T t);
int main() {
foo(1);
}
template<typename T>
T foo(T t)
{ std::cout << "A\n"; return 0; }
अगर मैं जिस तरह से मैं टेम्पलेट परिभाषा नाम जाहिरा तौर पर अब एक ही टेम्पलेट का उल्लेख में टेम्पलेट पैरामीटर का उपयोग बदलने के लिए, और जोड़ने में विफल रहता है।
#include <iostream>
template<typename T>
T foo(T t);
int main() {
foo(1);
}
template<typename T>
int foo(T t) { std::cout << "A\n"; return 0; }
// or
template<typename T>
struct identity {
typedef T type;
};
template<typename T>
typename identity<T>::type
foo(T t) { std::cout << "A\n"; return 0; }
इसके बाद, अगर मैं एक और अनुवाद इकाई के लिए टेम्पलेट परिभाषा ले जाते हैं, सी ++ (MSVC 11 बीटा) के अपने कार्यान्वयन के लिए कार्यक्रम कोई फर्क नहीं पड़ता कि कैसे मैं प्रकार कहते हैं कि काम करता है।
//main.cpp
template<typename T>
T foo(T t);
int main() {
foo(1);
}
//definition.cpp
#include <iostream>
template<typename T>
struct identity {
typedef T type;
};
template<typename T>
typename identity<T>::type
foo(T t) { std::cout << "A\n"; return 0; }
template int foo<int>(int);
या
//definition.cpp
#include <iostream>
template<typename T>
int foo(T t) { std::cout << "A\n"; return 0; }
template int foo<int>(int);
या यहां तक कि अगर परिभाषा एक टेम्पलेट बिल्कुल नहीं है:
//definition.cpp
#include <iostream>
int foo(T t) { std::cout << "A\n"; return 0; }
जाहिर जोड़ने क्योंकि हस्ताक्षर/घायल नाम एक ही है सफलता मिल रही है की परवाह किए बिना टेम्पलेट जो प्रतीक बनाने के लिए तत्काल था। मैं इस अपरिभाषित व्यवहार क्योंकि मैं का उल्लंघन कर रहा हूँ लगता है:
§ 14.1 [अस्थायी] p6
एक समारोह टेम्पलेट, एक वर्ग टेम्पलेट के सदस्य समारोह, या स्थिर डेटा सदस्य एक वर्ग टेम्पलेट का करेगा प्रत्येक अनुवाद इकाई में परिभाषित किया गया है जिसमें यह तत्काल तत्काल (14.7.1) है जब तक कि संबंधित विशेषज्ञता स्पष्ट रूप से तत्काल (14.7.2) में कुछ अनुवाद इकाई है; कोई निदान की आवश्यकता नहीं है।
लेकिन फिर कहते हैं कि मैं दो स्थानों में से एक पर एक स्पष्ट इन्स्टेन्शियशन दूसरा अनुवाद इकाई में टेम्पलेट की एक परिभाषा डाल, और शामिल करके उन आवश्यकताओं को पूरा करने का प्रयास करें:
#include <iostream>
template<typename T>
T foo(T t) { std::cout << "A\n"; return 0; }
// Location 1
template<typename T>
int foo(int t) { std::cout << "B\n"; return 0; }
// Location 2
क्या नियम हैं एक स्पष्ट तत्कालता किस टेम्पलेट को संदर्भित करता है, इस बारे में असंबद्धता के बारे में? इसे स्थान 1 पर रखकर सही टेम्पलेट को तत्काल बनाया जा सकता है और अंतिम परिभाषा में उस परिभाषा का उपयोग किया जाना चाहिए, जबकि इसे स्थान 2 पर डालने पर अन्य टेम्पलेट को तुरंत चालू किया जा सकता है, और जो मेरा मानना है वह ऊपर 14.1 पी 6 के तहत अपरिभाषित व्यवहार है।
दूसरी ओर दो टेम्पलेट्स परिभाषाओं की एक अंतर्निहित इन्स्टेन्शियशन तो यह टेम्पलेट्स disambiguating के लिए शासन की तरह लगता है, कोई बात नहीं क्या पहला टेम्पलेट उठाता है इन परिस्थितियों में अलग है:
#include <iostream>
template<typename T>
T foo(T t) { std::cout << "A\n"; return 0; }
template<typename T>
int foo(int t) { std::cout << "B\n"; return 0; }
int main() {
foo(1); // prints "A"
}
कारण यह आया ऊपर this question से संबंधित है जहां प्रश्नकर्ता है कि एक ही आगे घोषणा की खोज की
template<typename T>
T CastScriptVarConst(const ScriptVar_t& s);
कई टेम्प्लेट परिभाषाओं की एक घोषणा के रूप में कार्य नहीं कर सकता है:
template<typename T>
typename std::enable_if<GetType<T>::value < SVT_BASEOBJ,T>::type
CastScriptVarConst(const ScriptVar_t& s) {
return (T) s;
}
template<typename T>
typename std::enable_if<!(GetType<T>::value < SVT_BASEOBJ)
&& std::is_base_of<CustomVar,T>::value,T>::type
CastScriptVarConst(const ScriptVar_t& s) {
return *s.as<T>();
}
और मैं टेम्पलेट परिभाषाओं और घोषणाओं के बीच संबंधों को बेहतर ढंग से समझना चाहता था।
पूर्ण कहानी के लिए "सी ++ टेम्पलेट्स: पूर्ण मार्गदर्शिका" की प्रतिलिपि उठाएं। और हाँ, यह मानक से अधिक पचाने योग्य है ... वास्तव में बहुत कुछ;) – 0xC0000022L