10

टेम्पलेट मेटाप्रोग्राम (टीएमपी) को देखते हुए, क्या सी ++ कंपाइलर्स बिल्ड आंकड़े तैयार करते हैं जो तत्काल कक्षाओं की संख्या को गिनते हैं? या क्या इस नंबर को स्वचालित रूप से प्राप्त करने का कोई और तरीका है? तो उदाहरण के लिए obiquitous भाज्यएक टीएमपी में तत्काल कक्षाओं की संख्या को स्वचालित रूप से गिनें?

#include <iostream> 

template<int N> struct fact { enum { value = N * fact<N-1>::value }; }; 
template<> struct fact<1> { enum { value = 1 }; }; 

int main() 
{ 
    const int x = fact<3>::value; 
    std::cout << x << "\n"; 
    return 0; 
} 

मैं वापस पाने के लिए चाहते हैं नंबर 3 (वास्तव बाद से < 3>, वास्तव < 2>, और यह तथ्य < 1> instantiated कर रहे हैं)। यह उदाहरण निश्चित रूप से मामूली है, लेकिन जब भी आप उपयोग करना शुरू करते हैं उदा। Boost.MPL, संकलन समय वास्तव में विस्फोट, और मैं जानना चाहता हूं कि इसमें से कितना छुपा वर्ग तात्कालिकता के कारण है। मेरा सवाल मुख्य रूप से विजुअल सी ++ के लिए है, लेकिन जीसीसी के उत्तर भी सराहना की जाएगी।

संपादित: विज़ुअल सी के लिए ++ स्टीफ़न टी Lavavej के videos/d1reportAllClassLayout में से एक से संकलन स्विच जोड़ने और एक ग्रेप + शब्द आउटपुट फ़ाइल पर भरोसा कर रही है, लेकिन यह (क) बढ़ जाती है संकलन है मेरे वर्तमान बहुत भंगुर दृष्टिकोण बार बार और (बी) regex 100% सही पाने के लिए मुश्किल है।

उत्तर

7

मैंने जीसीसी में one-line change बनाया है जो इसे प्रत्येक क्लास टेम्पलेट का नाम प्रिंट करता है क्योंकि यह इसे तुरंत चालू करता है। फ़ंक्शन टेम्पलेट्स के लिए इसे प्राप्त करने के लिए आप -quiet ध्वज के बिना सीधे C++ फ्रंट-एंड cc1plus पर कॉल कर सकते हैं।

मुझे अभी तक उचित जीसीसी विकल्प में बदलने के लिए गोल नहीं मिला है, यह मेरे अपने स्रोत पेड़ पर सिर्फ एक हैक है। मैं इसे प्लगइन के रूप में लागू करने के बारे में सोच रहा हूं, लेकिन यह मेरी TODO सूची के शीर्ष के पास नहीं है।

+0

+1। मैंने सुझाव दिया कि किसी भी ओपन सोर्स कंपाइलर को हैक करना बहुत आसान होना चाहिए, लेकिन आप वास्तव में इसे सबसे अच्छे तरीके से साबित कर सकते हैं (एक पैच लिखकर जो वास्तव में करता है)। – abarnert

+0

धन्यवाद! क्या होगा (हां, गुंजाइश आ रहा है!) सभी वर्ग टेम्पलेट्स का एक लॉग है और कुल तात्कालिकताओं की कुल संख्या या पूरी सूची की बजाय उनके तत्काल की संख्या है। शायद पूर्ण बिल्ड लॉग को पोस्ट-प्रोसेस करने के लिए एक पर्ल स्क्रिप्ट वह है जो मुझे कोशिश करनी चाहिए। – TemplateRex

+1

आउटपुट को 'awk -F' <'' {टेम्पलेट्स [$ 1] ++} END {टेम्पलेट्स में टी के लिए प्रिंट करें, प्रिंट टी, टेम्पलेट्स [टी]} ' –

2

, ज़ाहिर है, ऐसा करने के लिए कोई पोर्टेबल तरीका नहीं है।

अधिकांश कंपाइलरों के लिए ऐसा करने के लिए हैकी तरीके हैं। आप पहले से ही एमएसवीसी के लिए एक पाया है। जीसीसी के लिए, आप शायद gccxml का उपयोग कर सकते हैं। या, किसी भी ओपन सोर्स कंपाइलर (जीसीसी या क्लैंग) के लिए, यह तत्कालता के बिंदु पर कोड जोड़ने के लिए बहुत आसान होना चाहिए जो या तो गिनती रखता है, या कुछ ऐसा लॉग करता है जिसे आप संकलित करने के बाद फ़िल्टर कर सकते हैं।

क्लैंग/एलएलवीएम के लिए, आप केवल एक प्लगइन बना सकते हैं जो तत्कालता को हुक करता है, जो कि बहुत साफ है, लेकिन शायद वास्तव में अधिक काम करता है।

डीबग प्रतीकों के साथ एक बिल्ड, कोई अनुकूलन नहीं, और कोई स्ट्रिपिंग प्रत्येक तत्कालता के उलझन वाले नामों के साथ खत्म हो सकती है, जिसे आप grep कर सकते हैं। हालांकि, कुछ कंपाइलर्स (जीसीसी समेत) कम से कम कुछ विधियों को रेखांकित करेंगे, चाहे आप उन्हें चाहते हों या नहीं।

template<int N> struct fact { 
    enum { value = N * fact<N-1>::value }; 
    int *dummy() { return &fact<N-1>::value; } 
}; 
+0

धन्यवाद!कोड को संशोधित करना वास्तव में एक विकल्प नहीं है क्योंकि 99% तत्काल वर्ग टेम्पलेट Boost.MPL और आदि से हैं, और मैं उन लोगों की एक साफ गिनती भी चाहता हूं। – TemplateRex

+0

मेरा मानना ​​है कि एमएसवीसी को बिल्कुल सभी इनलाइनिंग और ऑप्टिमाइज़ेशन को बंद करने के लिए सेट किया जा सकता है, जिसका मतलब है कि आपको सबकुछ के लिए ऑफ-ऑफ-लाइन इंस्टेंटेशन मिलेगा, लेकिन मुझे नहीं लगता कि किसी अन्य कंपाइलर की ऐसी सेटिंग्स हैं। – abarnert

1

एक उपकरण स्टीवन वातानाबे ने लिखा है कि गिनती करने के लिए इस्तेमाल किया जा सकता है: यदि आप अपने कोड को संशोधित करने को तैयार हैं, तो आप शायद बाहर के लाइन instantiations, हो सकता है कुछ इस तरह उत्पन्न करने के लिए यह मजबूर कर सकते हैं टेम्पलेट तत्काल की संख्या। आप इसे here प्राप्त कर सकते हैं। असल में, यह कोड को संशोधित करता है ताकि प्रत्येक बार कक्षा को तत्काल चालू करने पर एक कंपाइलर चेतावनी उत्पन्न हो और आप परिणामी पाठ को रेगेक्स के साथ संसाधित कर सकें, उदाहरण के लिए।

+0

धन्यवाद, मैं कोशिश करूँगा। – TemplateRex