मान लें हम इस तरह const char *
के गैर प्रकार पैरामीटर के साथ एक टेम्पलेट समारोह करते हैं:कुछ कॉन्स char * संकलन समय पर अनुपलब्ध हैं?
template <const char * MESSAGE> void print() {
std::cout << MESSAGE << '\n';
}
इस टेम्पलेट का उपयोग कर लॉग के रूप में एक समस्या नहीं होगा के रूप में MESSAGE
संकलन समय पर निष्कर्ष निकाला जा सकता है, तो निम्नलिखित का उपयोग करता है कानूनी हैं:
namespace {
char namespace_message[] = "Anonymous Namespace Message";
constexpr char namespace_constexpr_message[] = "Anonymous Namespace Constexpr Message";
}
char message[] = "Message";
constexpr char constexpr_message[] = "Constexpr Message";
int main()
{
print<namespace_message>();
print<namespace_constexpr_message>();
print<message>();
print<constexpr_message>();
return 0;
}
लेकिन नीचे वाले (see here) नहीं हैं:
namespace {
const char namespace_const_message[] = "Anonymous Namespace Const Message";
}
const char const_message[] = "Const Message";
int main()
{
print<namespace_const_message>();
print<const_message>();
print<"Literal">();
return 0;
}
कोड द्वारा उत्पन्न त्रुटियों ऊपर निम्नलिखित हैं:
the value of '{anonymous}::namespace_const_message' is not usable in a constant expression
मैं क्यों namespace_const_message
एक निरंतर अभिव्यक्ति में namespace_message
है, जबकि प्रयोग करने योग्य नहीं है नहीं मिलता है; अगर मुझे निरंतर अभिव्यक्ति में उपयोग करने में असमर्थ होने के लिए शर्त लगानी पड़े तो मैं निरंतर अभिव्यक्ति के लिए शर्त लगाऊंगा, लेकिन वह वह है जो पहले से ही निरंतर अभिव्यक्ति के रूप में काम करता है!
note: '{anonymous}::namespace_const_message' was not declared 'constexpr'
namespace_message
न constexpr
के रूप में घोषित किया गया था और एक निरंतर अभिव्यक्ति में प्रयोग किया जाता है और इसके मूल्य संकलन समय पर निष्कर्ष निकाला गया है। constexpr
की आवश्यकता क्यों है यदि अभिव्यक्ति const
है और यदि आवश्यक नहीं है तो आवश्यकता नहीं है?
अनाम नामस्थान के बाहर के मूल्यों के लिए भी जाता है, मैं मूल्यों को एक आंतरिक संबंध स्थान में रखकर संकलन-समय-स्थिरता को मजबूर करने की कोशिश कर रहा था लेकिन यह स्पष्ट है कि मैं असफल रहा हूं।
अंत में, पिछले त्रुटि:
'"Literal"' is not a valid template argument for type 'const char*' because string literals can never be used in this context
तो, आश्चर्यजनक रूप से एक स्ट्रिंग शाब्दिक टेम्पलेट तर्क के रूप में नहीं किया जा सकता (कम से कम यह एक आश्चर्य मेरे लिए था), लेकिन जब तक स्ट्रिंग के रूप में (अच्छी तरह से, एक अक्षरों की एक नल-टर्मिनेटेड सरणी के लिए सूचक) एक संकलन-समय मान है जिसे इसे गैर-प्रकार के टेम्पलेट पैरामीटर के रूप में उपयोग किया जा सकता है: वे संकलित समय पर उपलब्ध हैं जब तक कि वे "एक लालसा हैं" (लेकिन वे हैं already lvalues!)।
मैं अनुमान लगाने की कोशिश कर रहा हूं कि इस संदर्भ में स्ट्रिंग अक्षर का कभी भी उपयोग क्यों नहीं किया जा सकता है, और मेरा सबसे अच्छा अनुमान यह है कि एक ही सामग्री वाले दो स्ट्रिंग अक्षर एक ही शाब्दिक नहीं हैं (क्योंकि सूचक जो सामग्री को इंगित करता है अलग हो सकता है) जबकि दो अभिन्न शब्द समान हैं (वे एक मूल्य हैं, मूल्य के लिए सूचक नहीं)।
तो, यहां सवाल क्या है?
- क्यों
namespace_const_message
औरconst_message
संकलन समय पर उपलब्ध नहीं हैं और इस तरहprint
टेम्पलेट समारोह में मना? - क्या स्ट्रिंग अक्षर के बारे में मेरा अनुमान सही है?
धन्यवाद।
संबंध के बारे में महान जवाब! अच्छा है। मैं आपको लिंक मुद्दे के बारे में अधिक जानकारी के लिए पूछना चाहता हूं; AFAIK एक अज्ञात नेमस्पेस आंतरिक लिंकेज को मजबूर करता है और आप कहते हैं कि * बाहरी लिंकेज के लिए आवश्यक टेम्पलेट का तत्काल चर * *, टेम्पलेट में 'नेमस्पेस_मेसेज' और 'नेमस्पेस_कॉनएक्सएक्स_मेसेज' क्यों स्वीकार किए जाते हैं? क्या आप (कृपया) अपना उत्तर बढ़ा सकते हैं? –
@PaperBirdMaster: यह अनाम नामों के बारे में सच नहीं है। यह सी ++ 11 के फुटनोट 94: _ में स्पष्ट है: "हालांकि एक अनाम नामस्थान में इकाइयों के पास बाहरी संबंध हो सकता है, लेकिन वे प्रभावी रूप से उनके अनुवाद इकाई के नाम से योग्यता प्राप्त कर सकते हैं और इसलिए किसी भी अन्य अनुवाद इकाई से कभी नहीं देखा जा सकता है।" _ नियम 3.5/3 और 3.5/4 में दिए जाते हैं। –
@LightnessRacesinOrbit ठीक है, इसलिए मैं नामित नामस्थानों के बारे में गलत था: वे आंतरिक संबंध को मजबूर नहीं करते हैं, उनके पास आंतरिक संबंध हो सकता है। स्पष्टीकरण के लिए धन्यवाद। –