2010-10-07 19 views
22

यह C++ 0x में कैसे किया जाता है?std :: C++ 0x lambda अभिव्यक्ति का उपयोग करके परिवर्तन

std::vector<double> myv1; 
std::transform(myv1.begin(), myv1.end(), myv1.begin(), 
       std::bind1st(std::multiplies<double>(),3)); 

मूल प्रश्न और समाधान here है।

+0

.... क्या यह इस अन्य पोस्ट से लिया गया था? http://stackoverflow.com/questions/3885095/c-multiply-vector-elements-by-a-scalar-value-using-stl – ianmac45

+0

@ ianmac45 - हाँ, मैंने इसे ऊपर से –

+0

आह से जोड़ा है, ठीक है। याद किया कि – ianmac45

उत्तर

26
std::transform(myv1.begin(), myv1.end(), myv1.begin(), 
    [](double d) -> double { return d * 3; }); 
+20

'-> डबल 'अनावश्यक है; यह स्वचालित रूप से कम हो जाता है। – Potatoswatter

+4

@ पोटाटो - यह माना जाता है, लेकिन वर्तमान कंपाइलर कभी-कभी इस तथ्य को अनदेखा करते हैं। बस इसे हर समय रखने के लिए बेहतर है। –

+1

इसका एक वैकल्पिक तरीका है: 'std :: transform (myv1.begin(), myv1.end(), myv1.begin(), myv1.end(), std :: bind (std :: गुणा () , _1,3)); ' –

5
इस तरह

:

vector<double> myv1; 
transform(myv1.begin(), myv1.end(), myv1.begin(), [](double v) 
{ 
    return v*3.0; 
}); 
+3

मुझे लगता है कि स्वरूपण बहुत भ्रमित है। – Potatoswatter

+2

प्रत्येक के लिए, मुझे लगता है। मैं यह इंगित करता हूं कि मेरा * सही स्वरूपण है। :) –

+1

वास्तव में स्थिर के लिए एक शाब्दिक डबल का उपयोग करने के लिए +1। ;-) –

26

बस दारियो के रूप में क्या कहते हैं:

for_each(begin(myv1), end(myv1), [](double& a) { a *= 3; }); 

for_each हुए कहा कि यह एक मिथक है नहीं कर सकते, तत्वों को संशोधित करने की अनुमति है।

+1

+1 क्योंकि यह "प्रश्न_ईच तत्वों को संशोधित करने की अनुमति है" के लिए मूल प्रश्न –

+0

+1 में मेरे लिए अधिक प्राकृतिक फिट लगता है। मैंने इस साल पहले एक बहुत ही गर्म बहस में भाग लिया था। –

7

एक परिवर्तनीय दृष्टिकोण का उपयोग करके, हम संदर्भों के माध्यम से अनुक्रम तत्वों को सीधे अद्यतन करने के लिए for_each का उपयोग कर सकते हैं।

for_each(begin(myv1), end(myv1), [](double& a) { a *= 3; }); 


यह बहस का मुद्दा हो रहा है, तो for_each वास्तव में के रूप में यह एक "गैर-परिवर्तनशील" एल्गोरिथ्म कहा जाता है तत्वों को संशोधित करने की अनुमति दी है किया गया है।

क्या इसका मतलब है कि for_eachअनुक्रम यह पर चल रही है (- जो कि अमान्य iterators जो अनुक्रम संरचना के परिवर्तन करने के लिए संदर्भित करता है) को बदलने के लिए अनुमति नहीं है। इसका मतलब यह नहीं है कि हम सामान्य रूप से वेक्टर के गैर-कॉन्स तत्व को संशोधित नहीं कर सकते हैं - संरचना को इन परिचालनों से छूटा नहीं जाता है।

26

सी ++ में इन मामलों के लिए उस कार्यात्मक शैली का उपयोग करने के लिए मुख्य मूल प्रेरणा थी, "aaagh! Iterator loops!", और सी ++ 0x उस कथन के लिए सीमा-आधारित के साथ प्रेरणा को हटा देता है। मुझे पता है कि सवाल के बिंदु का हिस्सा लैम्ब्डा सिंटैक्स को ढूंढना था, लेकिन मुझे लगता है कि सवाल का जवाब "यह सी ++ 0x में कैसे किया जाता है?" है:

for(double &a : myv1) { a *= 3; } 

कोई वास्तविक समारोह वस्तु नहीं है, लेकिन अगर यह आपकी मदद करता है नाटक कर सकता है कि { a *= 3; } एक बेहद संक्षिप्त लैम्ब्डा है। प्रयोज्यता के लिए यह किसी भी तरह से किसी भी तरह की मात्रा में है, हालांकि मसौदा मानक समतुल्य for लूप के संदर्भ में श्रेणी-निर्धारित परिभाषित करता है।

+0

आह याह। मैं आमतौर पर इसके बारे में भूल जाता हूं क्योंकि मैं इसका उपयोग करने वाले कंपाइलर का उपयोग नहीं करता हूं। :(निश्चित रूप से सबसे अच्छा समाधान। – GManNickG

+0

इस निर्माण के लिए नाम क्या है? मैं अभी भी सी ++ 0x में क्या परिचित नहीं हूं। –

+1

"कथन के लिए रेंज-आधारित", 6.530 एन 30 9 0 में। उत्तर में जोड़ा गया –

1

मैं वीएस2012 का उपयोग कर रहा हूं जो सी ++ 11 बाइंड एडाप्टर का समर्थन करता है। बाइनरी फ़ंक्शन के पहले तत्व को बाध्य करने के लिए (जैसा कि बाइंड 1 वें करने के लिए उपयोग किया जाता है) आपको _1 (प्लेसहोल्डर तर्क) जोड़ने की आवश्यकता है। बांधने के लिए कार्यात्मक शामिल करने की आवश्यकता है।

using namespace std::placeholders; 
std::transform(myv1.begin(), myv1.end(), myv1.begin(), 
       std::bind(std::multiplies<double>(),3,_1)); 
संबंधित मुद्दे