मैं आज टेम्पलेट्स के साथ खेल रहा था यह देखने के लिए कि क्या मैं कंपाइलर को बाहरी कक्षा के प्रकार को अपने आंतरिक वर्गों में से किसी एक को कम करने के लिए प्राप्त कर सकता हूं। मुझे मेरा समाधान नहीं मिला (जो मुझे संदेह है असंभव है), लेकिन एक त्रुटि को ठीक करने का प्रयास करते समय मैं बहुत अजीब व्यवहार में भाग गया कि मैं निम्नलिखित स्निपेट में कमी आई।क्या यह बेतुका कोड है जो क्लेंग और जीसीसी दोनों में एक बग ठीक करता है?
struct A
{
struct B{};
template <typename T>
struct EverythingIsFine
{
using Outer = T;
using Inner = typename T::B::B::B::B::B::B;
};
using ItWillBeOkay = EverythingIsFine<B>; // Probably not ok
using InnerProblem = ItWillBeOkay::Inner; // Still not ok
using OuterProblem = decltype(B().ItWillBeOkay::Outer::B::B::B
::B::B::B::~B()); // Not even CLOSE to ok
};
यह आश्चर्यजनक रूप से कोई चेतावनी के साथ संकलित करता है और क्लैंग और जीसीसी दोनों के साथ कोई त्रुटि नहीं है।
मेरे कंपाइलर के संस्करण gcc version 5.3.1 20160121 (Debian 5.3.1-7)
और Debian clang version 3.6.2-3 (tags/RELEASE_362/final) (based on LLVM 3.6.2)
हैं और संकलित करने के लिए उपयोग किए गए ध्वज -std=c++11 -Wall -Wextra
हैं।
मैंने देखा कि यह ठीक on Ideone with the C++14 setting भी संकलित करता है।
मैं तो यह साधारण परीक्षण का इस्तेमाल किया InnerProblem
और OuterProblem
का सही प्रकार प्राप्त करने के लिए:
template <class T> void Type();
int main()
{
Type<A::InnerProblem>();
Type<A::OuterProblem>();
}
और जब परीक्षण संकलन दोनों compilers एक ही प्रकार की रिपोर्ट:
In function
main
:
main.cpp:20: undefined reference tovoid Type<A::B>()
main.cpp:21: undefined reference tovoid Type<void>()
कि कहने के लिए, InnerProblem
का प्रकार A::B
है और OuterProblem
का प्रकार void
है।
क्या यह किसी भी तरह से मानक द्वारा अनुमत है या यह दोनों कंपाइलरों में एक बग है?
और जब से मैं अपने कंपाइलर के रूप में उलझन में प्रतीत होता हूं, वास्तव में इस कोड के साथ क्या हो रहा है?
संपादित करें: सरलीकृत अनुवर्ती के रूप में, क्योंकि मुझे समझ में नहीं आता कि दो कंपाइलर एक ही परिणाम क्यों नहीं दे सकते हैं, निम्नलिखित कोड क्लैंग के साथ संकलित करता है, लेकिन जीसीसी के साथ नहीं।
struct A
{
struct B{};
template <typename T>
struct EverythingIsFine
{
using Inner = typename T::B::B::B;
};
using Problem = EverythingIsFine<B>::Inner::B::B::B; // Not ok
};
जीसीसी अब निम्न त्रुटि आउटपुट:
main.cpp:11:26: error: 'A::B::B' names the constructor, not the type using InnerProblem = EverythingIsFine::Inner::B::B::B; // Not ok
यह कोड आईसीसी और एमएसवीएस पर भी संकलित करता है – NathanOliver
नया प्रश्न -> नया प्रश्न कृपया। यदि संदर्भ मदद करता है तो एक लिंक शामिल करें। –
@ बाममितएगेन मुझे लगता है कि मेरा नया प्रश्न भी एक डुप्लिकेट होगा, इसलिए मैं इस बार रहूंगा, लेकिन आप सही हैं। – tux3