"…" ... टोकन का अर्थ क्या है? यानी पैरामीटर पैक पर डबल एलिप्सिस ऑपरेटर


110

नए सी ++ 11 हेडर के वर्तमान कार्यान्वयन के माध्यम से ब्राउज़ करते समय, मैंने "......" टोकन पर ठोकर खाई। आप जाँच सकते हैं, कि निम्नलिखित कोड ठीक है [ideone.com के माध्यम से]।

template <typename T>
struct X
{ /* ... */ };

template <typename T, typename ... U>
struct X<T(U......)> // this line is the important one
{ /* ... */ };

तो, इस टोकन का अर्थ क्या है?

संपादित करें: ऐसा लगता है कि SO शीर्षक "......" को "शीर्षक" में "..." की तरह लगाया गया है, मेरा वास्तव में मतलब "......" था। :)


संकेत: इसके ...बाद है ...
अलेक्जेंड्रे सी।

5
क्या इसके U...बाद यह अधिक पसंद नहीं है ...। फिर भी बहुत विषम।
eda-qa mort-ora-y

1
ध्यान दें: यह में पाया जा सकता <functional>है और <type_traits>, हमेशा टेम्पलेट पैरामीटर के अंदर एक समारोह तर्क सूची के संदर्भ में।
Potatoswatter

जिस तरह से मैंने इसे शीर्षक में अटकाने के लिए पाया, वह एक अंतरिक्ष inbetween डाल दिया गया था ... आशा है कि यह पाठकों के लिए स्पष्ट करता है।
मथिउ एम।

@ माथिउ एम .: धन्यवाद, बहुत बेहतर!
Vitus

जवाबों:


79

उस विषमता के प्रत्येक उदाहरण को एक नियमित एकल दीर्घवृत्त के मामले के साथ जोड़ा जाता है।

  template<typename _Res, typename... _ArgTypes>
    struct _Weak_result_type_impl<_Res(_ArgTypes...)>
    { typedef _Res result_type; };

  template<typename _Res, typename... _ArgTypes>
    struct _Weak_result_type_impl<_Res(_ArgTypes......)>
    { typedef _Res result_type; };

  template<typename _Res, typename... _ArgTypes>
    struct _Weak_result_type_impl<_Res(_ArgTypes...) const>
    { typedef _Res result_type; };

  template<typename _Res, typename... _ArgTypes>
    struct _Weak_result_type_impl<_Res(_ArgTypes......) const>
    { typedef _Res result_type; };

मेरा अनुमान है कि डबल _ArgTypes..., ...एलिप्सिस अर्थ के समान है , यानी सी-स्टाइल वैरिएग सूची के बाद एक वैरेडिक टेम्पलेट विस्तार।

यहाँ उस सिद्धांत का समर्थन करने वाला एक परीक्षण है ... मुझे लगता है कि हमारे पास सबसे खराब छद्म ऑपरेटर के लिए एक नया विजेता है।

संपादित करें: यह अनुरूप प्रतीत होता है। .8.3.5 / 3 पैरामीटर सूची को बनाने का एक तरीका बताता है

पैरामीटर-घोषणा-सूची ऑप्ट ... ऑप्ट

तो डबल-एलिप्सिस एक पैरामीटर-पैक के साथ समाप्त होने वाले पैरामीटर-डिक्लेरेशन-लिस्ट द्वारा बनता है, इसके बाद एक और एलिप्सिस होता है।

अल्पविराम विशुद्ध रूप से वैकल्पिक है; §8.3.5 / 4 कहता है

जहां वाक्यगत रूप से सही है और जहां "..." एक सार-घोषणाकर्ता का हिस्सा नहीं है, "..." ... "..." का पर्याय है।

यह है एक सार-declarator भीतर, [संपादित करें] लेकिन जोहानिस एक अच्छा मुद्दा यह है कि वे एक पैरामीटर-घोषणा के भीतर एक सार-declarator की बात कर रहे बनाता है। मुझे आश्चर्य है कि उन्होंने "पैरामीटर-घोषणा का हिस्सा" क्यों नहीं कहा, और यह वाक्य सिर्फ एक सूचनात्मक नोट क्यों नहीं है ...

इसके अलावा, va_begin()में <cstdarg>एक पैरामीटर की आवश्यकता से पहले सूची varargs, इसलिए प्रोटोटाइप f(...)विशेष रूप से सी द्वारा अनुमति ++ बेकार है। C99 के साथ क्रॉस-रेफरेंसिंग, यह सादे सी में अवैध है। इसलिए, यह सबसे विचित्र है।

उपयोग नोट

अनुरोध के अनुसार, यहां डबल दीर्घवृत्त का प्रदर्शन है:

#include <cstdio>
#include <string>

template< typename T >
T const &printf_helper( T const &x )
    { return x; }

char const *printf_helper( std::string const &x )
    { return x.c_str(); }

template< typename ... Req, typename ... Given >
int wrap_printf( int (*fn)( Req... ... ), Given ... args ) {
    return fn( printf_helper( args ) ... );
}

int main() {
    wrap_printf( &std::printf, "Hello %s\n", std::string( "world!" ) );
    wrap_printf( &std::fprintf, stderr, std::string( "Error %d" ), 5 );
}

हाँ य़ह सही हैं। टी (यू ..., ...) हालांकि ठीक भी संकलित करता है; शायद वे कुछ जगह बचाना चाहते थे। :)
वित्स

1
लेकिन इसका क्या मतलब होगा? और कंपाइलर कैसे बता सकता है कि _ArgTypes कहां समाप्त होता है और कुछ "अतिरिक्त" पैरामीटर शुरू होते हैं?
बो पर्सन

12
@Bo पेरसन: std::is_functionकी valueभले ही समारोह सी एक varargs और क्योंकि टी (यू ...) है सच होना चाहिए नहीं इस तरह के समारोह के लिए मेल खाते हैं, तो आप इस पागलपन की जरूरत है। जैसे int int f (int, char, ...) T = (int ......, U = {int, char} और "..." varargs टोकन के साथ T (U ......) से मेल खाता है।
वितुस

4
"यह है एक सार-declarator भीतर" -> वे कहते हैं कि एक ही पैरामीटर प्रकार सूची के अंतिम पैरामीटर का सार declarator का हिस्सा नहीं मतलब है। जैसे void (int...)यहां, ...अमूर्त-घोषणाकर्ता का हिस्सा नहीं है int, इसलिए यह इसका पर्याय है void(int, ...)। यदि आप लिखते हैं void(T...)और Tएक टेम्पलेट पैरामीटर पैक है, ...तो सार-घोषणाकर्ता का हिस्सा होगा, और इसलिए यह समकक्ष नहीं होगा void(T, ...)
जोहान्स शाउब -

2
"इसके अलावा, va_begin () <cstdarg> में varargs सूची से पहले एक पैरामीटर की आवश्यकता होती है, इसलिए प्रोटोटाइप f (...) विशेष रूप से C ++ द्वारा अनुमत बेकार है।" - यह केवल बेकार है यदि आप जानना चाहते हैं कि क्या तर्क पारित किए गए थे। f(...)टेम्प्लेट मेटाप्रोग्रामिंग में फ़ॉलबैक फ़ंक्शन ओवरलोड के रूप में अत्यधिक उपयोग किया जाता है, जहां यह जानकारी आवश्यक नहीं है (और जहां फ़ंक्शन वास्तव में कॉल नहीं किया जाता है)।

4

टेम्पलेट संस्करण में vs2015 को अलग करना अल्पविराम आवश्यक है:

    template <typename T, typename ... U>
    struct X<T(U...,...)> {};// this line is the important one

एक उदाहरण तात्कालिकता है:

    X<int(int...)> my_va_func;

का संबंध है, एफएम।


मैंने अभी भी इस पर ध्यान दिया है, यह अभी भी होता है। Developercommunity.visualstudio.com/content/problem/437260/… पर बग रिपोर्ट ।
२१

जानकार अच्छा लगा। इस बारे में किसी भी संदर्भ या गतिरोध?
रेड .व्यू २ Red

.سلام ببخشید نمیدانم
इगनीक

यह पब्लिक फ़ोरम है। लोगों को वह पढ़ने दें जो आप सोचते हैं। PLZ निजी संदेशों के लिए देशी लैंग रखें। سپاس।
रेड। वेव

ठीक है फिर। मैं मानक का कोई विशेषज्ञ नहीं हूं - मुझे लगता है कि दूसरों ने इसे ऊपर कुछ विस्तार से कवर किया है। यदि कोई Microsoft समस्या रिपोर्ट पर टिप्पणी करने की परवाह करता है तो वह अपनी प्राथमिकता बढ़ा सकता है। रिपोर्ट दिखाती है कि कुलपति ++ की अनुमति देने के लिए क्लैग और जीसीसी दिखाते हैं इसलिए मुझे नहीं लगता कि हम संभवतः काफी मजबूत जमीन पर हैं।
२१
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.