2016-12-07 34 views
15

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

template< typename A, typename B > 
struct Foo { 
    Foo(A const &a, B const &b) 
      : a_(a), b_(b) 
    { } 

    A a_; 
    B b_; 
}; 

template< typename A, typename B > 
using Bar = Foo<A, B>; 

auto foobar() { 
    Foo r{1, 2}; 
    Bar s{3, 4}; 
    // ../src/geo/vector_test_unit.cpp: In function 'auto foobar()': 
    // ../src/geo/vector_test_unit.cpp:16:6: error: missing template arguments before 's' 
    // Bar s{3, 4}; 
    //  ^
    return 1; 
} 

आप के ऊपर एक कोड टिप्पणी से देख सकते हैं, जी ++ मुझे दे रहा है: हालांकि, टेम्पलेट तर्क कटौती जो केवल आगे लक्ष्य वर्ग के लिए सीधे एक सरल उर्फ ​​टेम्पलेट से एक वस्तु के निर्माण के लिए काम नहीं करता है टेम्पलेट तर्क के बिना उपनाम टेम्पलेट का उपयोग करने के बारे में एक त्रुटि। मैं इस तरह के एक उदाहरण में उम्मीद कर रहा था कि टेम्पलेट तर्क कटौती अग्रेषित की जाएगी।

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

मैं समझ सकता हूं कि चूंकि उपनाम टेम्पलेट्स में किसी भी प्रकार का टेम्पलेट पैरामीटर हो सकता है क्योंकि संकलक के लिए लक्ष्य वर्ग टेम्पलेट तर्कों को सफलतापूर्वक कम करने के लिए यह संभव नहीं हो सकता है, लेकिन इस तरह के मामले में मैं उम्मीद करता हूं कि संकलक होगा उसी तरह से सक्षम है कि यह सीधे लक्षित वर्ग के लिए कर सकता है।

मैं केवल कुछ दिन पहले सिर से निर्मित जीसीसी के साथ --std=c++1z का उपयोग कर निर्माण कर रहा हूं। पूर्ण संस्करण जानकारी है: gcc version 7.0.0 20161201 (experimental) (Homebrew gcc HEAD- --with-jit)

उत्तर

21

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

template<typename T> struct Q { Q(T); };  // #1 
template<typename T> struct Q<T*> { Q(T); }; // #2 
template<typename T> using QP = Q<T*>; 
int *x; 
Q p = x; // deduces Q<int*> using #1, ill-formed 
QP q = x; // deduces Q<int*> using #1, or 
      // deduces Q<int**> using #2? 

template<typename T> Q(T) -> Q<T>; // #3 
QP r = x; // can we use deduction guide #3 here? 

template<typename T> Q(T*) -> Q<T**>; // #4 
int **y; 
QP s = y; // can we use deduction guide #4 here? 

template<typename T> struct A { typedef T type; struct Y {}; }; 
template<typename T> using X = typename A<T>::type; 
template<typename T> using Y = typename A<T>::Y; 
X x = 4;   // can this deduce T == int? 
X y = A<int>::Y(); // can this deduce T == int? 

उपरोक्त प्रश्नों को सभ्य जवाब नहीं है, लेकिन उनमें से निपटने जटिलता ला देता है, और इसके लिए सी ++ 17 उर्फ ​​टेम्पलेट्स के लिए कटौती की अनुमति नहीं देने के बजाय कुछ भीड़ के लिए बेहतर लग रहा था त्रुटिपूर्ण।

मुझे भविष्यवाणी है कि हम इस सुविधा को सी ++ 20 के लिए प्रस्तावित फैसल से एक पेपर देखेंगे।

+0

मैं इसे एक बार में अपनी उदाहरण फ़ाइल को एक बिट में बना रहा हूं और इसे समझने की कोशिश करने के लिए संकलित कर रहा हूं। मैंने इसे केवल # 1, # 2, और लाइनों 'int * x का उपयोग करके संकलित किया है; क्यू पी = एक्स; '। यह एक त्रुटि देता है, जैसा कि आपने इंगित किया है, जब तक कि मैं # 2 को हटा नहीं देता और फिर संकलित करता हूं। G ++ से त्रुटि संदेश '[...] त्रुटि है: 'int *' से 'int' से अमान्य रूपांतरण ... क्यू पी = एक्स; ... नोट: 'क्यू :: क्यू (टी) [टी = int] के साथ तर्क 1 प्रारंभ करना' टेम्पलेट <टाइपनाम टी> स्ट्रक्चर क्यू {क्यू (टी); }; '। मेरे लिए ऐसा लगता है कि यह # 1 के बजाय # 2 का उपयोग करने की कोशिश कर रहा है जैसा आपने कहा था। मुझे क्या समझ में नहीं आ रहा है? –

+1

@ स्क्विडबिडनेस लाइन 'क्यू पी = एक्स;' वर्ग टेम्पलेट तर्क कटौती के लिए # 1 का उपयोग करके 'पी' के प्रकार को 'क्यू ' के रूप में घटाती है।उस प्रकार को चुनने के बाद, यह बताता है कि 'क्यू ' '' 0 =39' को घटाकर 'क्यू ' आंशिक विशेषज्ञता का उपयोग करना चाहिए। आखिरकार, यह 'Q ' कन्स्ट्रक्टर को 'int *' प्रकार के पैरामीटर के साथ कॉल करने का प्रयास करता है, जो काम नहीं करता है क्योंकि केवल कन्स्ट्रक्टर (डिफ़ॉल्ट/प्रतिलिपि/चालक ctors के अलावा) एक 'int' लेता है। –

+0

उस स्पष्टीकरण के लिए धन्यवाद। वह हिस्सा जो मुझे भ्रमित कर रहा था वह था कि मेरा मानसिक मॉडल 'पी' के प्रकार को कम कर रहा था और एक और एक ही प्रक्रिया के रूप में एक टेम्पलेट विशेषज्ञता चुन रहा था। यह इंगित करते हुए कि वे अलग-अलग कदम हैं, मुझे इसे बेहतर तरीके से तर्क देने में मदद करता है। –

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