2016-09-30 20 views
5

लैम्ब्डा भाव unevaluated संदर्भों में अनुमति नहीं है (उदाहरण के लिए में decltype) और हाल ही में जब तक निरंतर भाव नहीं हो सकता। इसलिए टेम्पलेट तर्कों में उनका उपयोग करने का कोई तरीका नहीं था।का मूल्यांकन constexpr लैम्ब्डा गैर प्रकार टेम्पलेट तर्क में

सी ++ 17 में हालांकि निरंतर अभिव्यक्ति लैम्ब्डा संभव होगा। यह अभी भी सामान्य रूप से टेम्पलेट तर्कों में उनका उपयोग करने की अनुमति नहीं देता है।

हालांकि गैर प्रकार टेम्पलेट तर्क निरंतर अभिव्यक्ति लैम्ब्डा भाव एक से मूल्यांकन के संदर्भ में इस्तेमाल किया जा सकता, उदाहरण के लिए के लिए विशेष रूप:

template<int N> struct S { constexpr static int value = N; }; 

int main() { 
    int N = S<[]()constexpr{return 42;}()>::value; 
} 

कि अभी भी काम नहीं करता, क्योंकि लैम्ब्डा भाव स्पष्ट रूप से टेम्पलेट में अनुमति नहीं है तर्क या प्रकार या गैर प्रकार के तर्क।

मेरा प्रश्न उपरोक्त निर्माण की अनुमति नहीं देने के पीछे तर्क है। मैं समझ सकता हूं कि फ़ंक्शन हस्ताक्षर में लैम्ब्डा के प्रकार समस्याग्रस्त हो सकते हैं, लेकिन यहां बंद प्रकार स्वयं अप्रासंगिक है, केवल (संकलन-समय निरंतर) वापसी मान का उपयोग किया जाता है।

मुझे लगता है कारण यह है कि लैम्ब्डा शरीर में सभी बयानों टेम्पलेट तर्क अभिव्यक्ति का हिस्सा बनी और इसके परिणामस्वरूप SFINAE अगर शरीर में किसी भी बयान प्रतिस्थापन के दौरान बीमार बनाई है लागू किया जा करने की आवश्यकता होगी है। शायद कंपाइलर डेवलपर्स से महत्वपूर्ण काम की आवश्यकता होगी।

लेकिन वास्तव में यह मेरी प्रेरणा है। यदि उपर्युक्त निर्माण का उपयोग करना संभव था तो SFINAE न केवल निरंतर अभिव्यक्तियों के साथ प्रयोग किया जा सकता है, बल्कि अन्य बयान भी कॉन्सएक्स फ़ंक्शन (जैसे शाब्दिक प्रकार की घोषणाओं) में मान्य किया जा सकता है।

संकलक लेखकों पर प्रभाव के अलावा, कोई समस्या इस का कारण होता है, उदाहरण के लिए है मानक में अस्पष्टता, विरोधाभास या जटिलताओं?

+4

मुझे लगता है कि आप अपने खुद के सवाल का जवाब दे। – Barry

+0

खैर, +1 @ बैरी और यह वास्तव में एक दिलचस्प क्यू/ए है। – skypjack

+0

@ बररी मैंने थोड़ा सा प्रश्न मेरे प्रश्न को संशोधित किया। मुझे कुछ मान्यताओं की उम्मीद थी कि यह वास्तव में (केवल) प्रमुख कारण है, शायद तर्क का जिक्र करते हुए एक समिति पेपर/चर्चा का कुछ संदर्भ। – user4407569

उत्तर

2

यह काफी जानबूझकर कि lambdas unevaluated संदर्भों में दिखाई नहीं देते है। तथ्य यह है कि लैम्ब्डा हमेशा अनोखे प्रकार होते हैं, सभी प्रकार के मुद्दों की ओर जाता है।

यहाँ डैनियल Krugler से, एक comp.lang.c++ discussion से कुछ उदाहरण हैं:

वहाँ वास्तव में लैम्ब्डा भाव अनुमति देने के लिए के उपयोग के मामलों एक बड़ी संख्या मौजूद होगा, यह शायद बहुत संभव sfinae मामलों का विस्तार होगा (पूरा कोड "रेत-बक्से" शामिल करने के लिए)। कारण है कि वे बाहर रखा बन बिल्कुल sfinae मामलों में (आप संकलक के लिए एक भानुमती बॉक्स को खोलने थे) के इस चरम विस्तार और तथ्य के कारण किया गया है कि यह कर सकते हैं तुम्हारा के रूप में, उदाहरण के लिए अन्य उदाहरण पर समस्याओं का नेतृत्व

template<typename T, typename U> 
void g(T, U, decltype([](T x, T y) { return x + y; }) func); 

, क्योंकि हर लैम्ब्डा अभिव्यक्ति एक अद्वितीय प्रकार उत्पन्न करता है, बेकार है, इसलिए कुछ की तरह

g(1, 2, [](int x, int y) { return x + y; }); 

वास्तव में काम नहीं करता है क्योंकि पैरामीटर में प्रयोग किया जाता लैम्ब्डा के प्रकार से अलग है g पर कॉल में लैम्ब्डा का प्रकार।

अंत में यह नाम-उलझन के मुद्दों का भी कारण बन गया। जैसेआप

template<typename T> 
void f(T, A<sizeof([](T x, T y) { return x + y; })> * = 0); 
एक अनुवाद इकाई में

लेकिन

template<typename T> 
void f(T, A<sizeof([](T x, T y) { return x - y; })> * = 0); 

एक और अनुवाद इकाई में जब। अब मान लें कि आप दोनों अनुवाद इकाइयों से f<int> को तुरंत चालू करें। इन दो कार्यों में हस्ताक्षर अलग-अलग हैं, इसलिए उन्हें अलग-अलग मिश्रित टेम्पलेट तत्कालताएं उत्पन्न करनी होंगी। उन्हें अलग रखने का एकमात्र तरीका है lambdas के शरीर को उलझाना। बदले में, इसका मतलब है कि भाषा में हर तरह के बयान के लिए नाम मैंगलिंग नियमों के साथ आने के लिए कंपाइलर लेखकों के पास है। तकनीकी रूप से संभव होने पर, इसे विनिर्देश और कार्यान्वयन बोझ दोनों के रूप में माना जाता था।

समस्याओं की एक पूरी बंडल है कि। विशेष रूप से यह देखते हुए कि लेखन के अपने motiviation:

int N = S<[]()constexpr{return 42;}()>::value; 

आसानी बजाय लिख कर हल किया जा सकता:

constexpr auto f = []() constexpr { return 42; } 
int N = S<f()>::value; 
+0

बेशक अब मैंने इसे पोस्ट किया है, मैंने यह भी पाया [यह क्यू/ए] (http://stackoverflow.com/q/22232164/2069064)। – Barry

+0

मुझे समझ में नहीं आता कि टेम्पलेट तर्कों में समस्या क्या है, हालांकि: वे हस्ताक्षर का हिस्सा नहीं हैं, और एसएफआईएनएई लैम्ब्डा शरीर पर क्यों लागू होना चाहिए? – dyp

+0

@dyp SFINAE वास्तव में पहले स्थान पर लैम्ब्स रखने के लिए माध्यमिक है। मुझे लगता है कि मायने रखता है। – Barry

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