2017-01-19 11 views
9

मैं एक कक्षा के लिए एक सी ++ - आधारित असाइनमेंट डाल रहा हूं जिसे मैं पढ़ रहा हूं। मेरे पास एक ऐसा कार्य है जिसे मैं छात्रों को निर्यात कर रहा हूं कि मैं उन्हें अपने कार्यक्रम में विभिन्न बिंदुओं पर कॉल करना चाहता हूं ताकि ग्रेडिंग के दौरान, हम यह सुनिश्चित करने के लिए उन कॉलों को रोक सकते हैं कि वे सही समय पर सही चीजें कर रहे हैं । मैं नहीं चाहता कि कोड प्रदान की गई स्टार्टर फाइलों में कुछ भी करे, इसलिए मैंने फ़ंक्शन को एक ऐसा शरीर दिया है जिसमें केवल बयान की एक श्रृंखला है जो सभी तर्कों को void पर अप्रयुक्त तर्कों के बारे में संकलक चेतावनियों को दबाने के लिए रखती है। ऐसा करने के दौरान, मैं एक असामान्य कंपाइलर त्रुटि में भाग गया जो मैंने पहले कभी नहीं देखा है, और इस साइट पर एक खोज ने कुछ भी उपयोगी नहीं किया है।शून्य करने के लिए असामान्य संकलक त्रुटि कास्टिंग?

त्रुटि सबसे अच्छा this reduced test case द्वारा उदाहरण जा सकता है:

void iDontUseMyArguments(int a, int b) { 
    (void) a; // Explicit cast to void - totally fine! 
    (void) b; 
} 

void iDontEither(int a, int b) { 
    (void) a, b; // Comma expression casted to void, though technically 
        // b isn't casted to void! 
} 

void norDoI(int a, int b) { 
    void(a, b); // ERROR! No idea why this isn't okay. 
} 

void meNeither(int a, int b) { 
    (void)(a, b); // Comma expression casted to void - totally fine! 
} 

void jumpOnBandwagon(int a, int b) { 
    void((a, b)); // Comma expression casted to void - totally fine! 
} 

आप देख सकते हैं, इनमें से अधिकांश ठीक संकलन। मुद्दा यह एक में किया गया था:

void(a, b); 

यह निम्न त्रुटि से चलाता है:

prog.cpp: In function 'void norDoI(int, int)': 
prog.cpp:11:11: error: expression list treated as compound expression in functional cast [-fpermissive] 
    void(a, b); 
     ^

मैं यह त्रुटि संदेश का सामना करना पड़ा कभी नहीं किया है, तो मुझे यकीन है कि क्या यह मुझे बताने की कोशिश कर रहा है नहीं कर रहा हूँ।

लाइन

void(a, b); 

के पीछे मंशा a और b है कि तब casted था शामिल एक समारोह शैली डाली का उपयोग कर void टाइप करने के लिए एक अल्पविराम अभिव्यक्ति होना था। आप देख सकते हैं, के बाद सभी काम वेरिएंट:

(void)(a, b); 
void((a, b)); 

मुझे लगता है इस संभावना सबसे अप्रिय पार्स के साथ कुछ है और यह एक घोषणा के रूप में व्याख्या हो रही है, लेकिन विशेष रूप से त्रुटि मैं हो रही है नहीं है ऐसा लगता है।

  1. क्यों, वास्तव में, नहीं इस कोड को कानूनी है:

    मेरा प्रश्न पीछा कर रहा है?

  2. संकलक क्या सोचता है कि मैं करने की कोशिश कर रहा हूं?
  3. क्यों, वास्तव में, ये अन्य रूप कानूनी हैं?
+1

मैं कहूंगा, आपको पढ़ना शुरू करने से पहले बहुत कुछ सीखना होगा! – SergeyA

+3

@ सर्गेई कहने का क्या मतलब है। कौन कहता है कि वे सी ++ सिखाते हैं। – NathanOliver

+0

@NathanOliver, मुझे यकीन है कि ओपी सी ++ सिखाता है। अगर मैं गलत हूं, तो मैं क्षमा चाहता हूं। यदि मैं सही हूं, तो यह हमारे स्कूलों में प्रोग्रामिंग शिक्षा के साथ सभी समस्याओं का संकेत देगा। – SergeyA

उत्तर

7

इस संरचना को देखते हुए:

struct S { 
    S(int, int) {} 
}; 

S(1, 2) का क्या अर्थ है?

उत्तर: इसका मतलब है कि आप 1 और 2 मानों से S प्रकार का ऑब्जेक्ट बनाते हैं।


इस समारोह टेम्पलेट को देखते हुए:

template <typename T> T f() { return T(1, 2); } 

T(1, 2) क्या मतलब है?

उत्तर: यह आपको मान 1 और 2, जो संभव है से प्रकार T की एक वस्तु का निर्माण करता है, तो T उदाहरण पहला सवाल से प्रकार S के लिए है का मतलब है।


उसी फ़ंक्शन टेम्पलेट को देखते हुए, f<void>() का क्या अर्थ है?

उत्तर: यह दो मान 1 और 2 से एक एकल void मान बनाने का प्रयास करता है। यह विफल रहता है क्योंकि केवल एक मान को void में परिवर्तित किया जा सकता है।


void(1, 2)T(1, 2) से कुछ भी मतलब कुछ और जब Tvoid होने वाला है?

उत्तर: नहीं, इसका मतलब बिल्कुल वही बात है, यही कारण है कि यह एक त्रुटि है।

+0

यह सही समझ में आता है। तो कारण 'शून्य ((1, 2))' काम करता है कि यह एक तर्क सूची के रूप में पार्स नहीं किया जा सकता है और इसे अल्पविराम ऑपरेटर के उपयोग के रूप में पार्स किया जाना चाहिए? – templatetypedef

+0

@templatetypedef बहुत ज्यादा। मानक का व्याकरण इसे थोड़ा अलग तरीके से वर्णित करता है, लेकिन वास्तव में, यह आपकी टिप्पणी के समान ही बहुत कुछ है। – hvd

0

void(a, b); संकलक में "सोचें" कि आप फ़ंक्शन नाम के रूप में किसी प्रकार का उपयोग करने का प्रयास कर रहे हैं, इसलिए यह एक त्रुटि देता है।

अन्य मामलों प्रकार कास्टिंग रहे हैं ...

+0

बस संकलक द्वारा दिए गए संदेश से। http://stackoverflow.com/questions/4775781/what-is-the-difference-between-c-like-casting-functional-casting – Rama

+0

मुझे विश्वास नहीं है कि यह समस्या का मूल कारण है, क्योंकि आप इसका उपयोग कर सकते हैं इस तरह के संदर्भों में नाम टाइप करें। हालांकि धन्यवाद! – templatetypedef

3

documentation को देखते हुए मुझे लगता है कि आप रूपांतरण मामलों शासन में से एक का उल्लंघन किया है (# 3):

If there are more than one expression in parentheses, new_type must be a class with a suitably declared constructor. This expression is a prvalue of type new_type designating a temporary (until C++17)whose result object is (since C++17) direct-initialized with expressions.

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