5

मैंने कुछ समय एक कोड लिखा था जिसने कुछ टेम्पलेट मेटाप्रोग्रामिंग के लिए संकलन समय पर स्थिर तालिका/सरणी उत्पन्न की थी (विचार यह है कि सी-शैली तारों को संकलित समय पर बनाया जा सकता है (वे केवल char सरणी हैं)। विचार और कोड पर आधारित है David Lin के answer:स्टेटिक टेबल पीढ़ी जीसीसी के साथ काम करता है लेकिन झगड़ा नहीं; क्लैंग बग है?

#include <iostream> 

const int ARRAY_SIZE = 5; 

template <int N, int I=N-1> 
class Table : public Table<N, I-1> 
{ 
public: 
    static const int dummy; 
}; 

template <int N> 
class Table<N, 0> 
{ 
public: 
    static const int dummy; 
    static int array[N]; 
}; 

template <int N, int I> 
const int Table<N, I>::dummy = Table<N, 0>::array[I] = I*I + 0*Table<N, I-1>::dummy; 

template <int N> 
int Table<N, 0>::array[N]; 

template class Table<ARRAY_SIZE>; 

int main(int, char**) 
{ 
    const int *compilerFilledArray = Table<ARRAY_SIZE>::array; 
    for (int i=0; i < ARRAY_SIZE; ++i) 
     std::cout<<compilerFilledArray[i]<<std::endl; 
} 

जीसीसी 4.9.2 काम करता है के साथ इस कोड संकलन:

बजना 3.5 शिकायत है, हालांकि:

$ clang++ -Wall -pedantic b.cpp 
Undefined symbols for architecture x86_64: 
    "Table<5, 0>::dummy", referenced from: 
     ___cxx_global_var_init in b-b8a447.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

dummy और array दोनों को Table कक्षा (जहां उन्हें घोषित किया गया है) के बाहर दी गई परिभाषाएं दी गई हैं। जहां तक ​​मैं कह सकता हूं, यह लिंकर आवश्यकताओं को पूरा करना चाहिए।

क्या यह क्लैंग के साथ एक बग है?

उत्तर

6

प्रत्येक प्राथमिक और आंशिक विशेषज्ञता स्थिर डेटा सदस्यों को अलग से परिभाषित किया जाना चाहिए। प्राथमिक विशेषज्ञताओं स्थिर डेटा सदस्य -

template <int N, int I> 
const int Table<N, I>::dummy = …; 

केवल एक चीज यहां बताए गए Table<N, I>::dummy है। [Temp.class.spec.mfunc]/1 :

कक्षा टेम्पलेट आंशिक विशेषज्ञता सदस्यों को बताया कि एक तरह से एक परिभाषा परिभाषित किया जाएगा की आवश्यकता है कि में किया जाता है; प्राथमिक टेम्पलेट के सदस्यों की परिभाषाओं को क्लास टेम्पलेट आंशिक विशेषज्ञता के सदस्यों के लिए परिभाषा के रूप में कभी भी उपयोग नहीं किया जाता है।

यह भी दर्शाता है कि जीसीसी यहां गलत है। यह एक बग है।
Eitherway,

template <int N> 
const int Table<N, 0>::dummy = 0; 

जोड़ने ठीक संकलन चाहिए।


1) विशेष रूप से, उपर्युक्त उद्धरण के रूप में एक ही अनुभाग में:

एक वर्ग टेम्पलेट के एक सदस्य के टेम्पलेट पैरामीटर सूची आंशिक विशेषज्ञता के टेम्पलेट पैरामीटर सूची से मेल करेगा कक्षा टेम्पलेट आंशिक विशेषज्ञता।
कक्षा टेम्पलेट आंशिक विशेषज्ञता के सदस्य की टेम्पलेट तर्क सूची क्लास टेम्पलेट आंशिक विशेषज्ञता के टेम्पलेट तर्क सूची से मेल खाती है।

इसका मतलब है कि तर्क सूचियों आंशिक विशेषज्ञता और उसके सदस्य को परिभाषित करने में एक ही होना चाहिए के लिए इस्तेमाल किया। अन्यथा उस सदस्य को कभी परिभाषित नहीं किया जाता है।

+0

आह, यह समझ में आता है! यह एक शर्म की बात है कि मैं केवल एक बार मतदान कर सकता हूं। साथ ही, जब आप उन्हें प्राप्त करते हैं तो मैं मानक उद्धरणों की प्रतीक्षा कर रहा हूं। – Cornstalks

+0

@ कॉर्नस्टॉक वे वहां हैं :) – Columbo

+0

क्या आप कृपया जीसीसी बग रिपोर्ट में एक लिंक जोड़ सकते हैं? –

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