2010-12-07 17 views
5

किसी कारण से, मैं boost::lambda में boost::format का उपयोग करने में विफल रहता हूं।बूस्ट :: प्रारूप में बूस्ट :: प्रारूप का उपयोग :: लैम्ब्डा

#include <algorithm> 
#include <iomanip> 
#include <iostream> 

#include <boost/assign/list_of.hpp> 
#include <boost/format.hpp> 
#include <boost/lambda/lambda.hpp> 

namespace bl = boost::lambda; 

int main() 
{ 
    const std::vector<int> v = boost::assign::list_of(1)(2)(3); 
    std::for_each(v.begin(), v.end(), bl::var(std::cout) << std::setw(10) << bl::_1); 
    std::for_each(v.begin(), v.end(), bl::var(std::cout) << boost::format("%10d") % bl::_1); 
} 
  • पहले std::for_each उम्मीद उत्पादन
  • का उत्पादन दूसरे std::for_each केवल आउटपुट किसी भी संख्या

कि क्यों है बिना व्हाइटस्पेस: यहाँ एक (उम्मीद) मेरे कोड का compilable सरलीकरण है? मैं वास्तव में boost::lambda से परिचित नहीं हूं इसलिए मुझे यहां स्पष्ट रूप से याद आ रही है।

कृपया सुझाव नहीं देते std::copy आधारित जवाब: मेरी वास्तविक कोड std::vector पर लेकिन boost::fusion::vector पर काम नहीं करता है (और std::for_each तथ्य एक boost::fusion::for_each में है)।

उत्तर

4

किसी कारण से, आपका कोड लैम्ब्डा के प्रत्येक आमंत्रण के बजाय तुरंत boost::format("%10d") % bl::_1 का मूल्यांकन करता है।

इसे रोकने के लिए, आपको bl::var पर कॉल में boost::format("%10d") को लपेटने की आवश्यकता है, जैसा आपने std::cout के साथ किया है।

दुर्भाग्यवश, ऐसा करने के लिए बूस्ट.लैम्बा को operator% पर कॉल के रिटर्न प्रकार को कम करने की आवश्यकता है, जो यह करने में असमर्थ है। इसलिए bl::ret का उपयोग करके वापसी प्रकार को स्पष्ट रूप से निर्दिष्ट किया जाना चाहिए। ध्यान दें कि यह रिटर्न प्रकार एक संदर्भ होना चाहिए, ताकि std::cout इसकी प्रतिलिपि के बजाय सीधे लौटा ऑब्जेक्ट एक्सेस कर सके।

हम इस प्रकार निम्नलिखित कोड है, जो उम्मीद उत्पादन का उत्पादन मिलता है:

std::for_each(v.begin(), v.end(), bl::var(std::cout) << 
    bl::ret<const boost::format &>(bl::var(boost::format("%10d")) % bl::_1)); 
+0

हाँ, यह काम करता है, लेकिन मुझे नहीं पता कि यह क्यों जरूरी है! 'boost :: lambda :: var' केवल तभी जरूरी हो जब न तो तर्क लैम्ब्डा अभिव्यक्ति हो। मैं 'बूस्ट :: लैम्ब्डा' का उपयोग करके एक अच्छा और संक्षिप्त वाक्यविन्यास का लक्ष्य रख रहा था :(बहुत बुरा – icecrime

2

मेरी शर्त यह है कि आप इस तथ्य में भाग रहे हैं कि उपयोग किए गए प्रारूप अब उपयोग करने योग्य नहीं हैं।

boost::format f("..."); 

std::string s = f % ... ; 
std::string s2 = f % other options...; // FAIL! f has been changed by the above use! 

दूसरे शब्दों में, प्रारूप पर% का उपयोग करके वास्तव में स्ट्रिंग डेटा को जो कुछ भी आप इसमें डालते हैं उसे बदल देता है। कूलर चीज यह है कि उपरोक्त दूसरा उपयोग चुपचाप विफल हो जाएगा।

मुझे पता है, काउंटर-सहज ज्ञान युक्त, लेकिन यह वही है।

+0

अपने जवाब के लिए धन्यवाद, लेकिन मेरा मानना ​​है कि कोड आप अपेक्षा के अनुरूप काम करता है प्रदान की है। Boost.format दस्तावेज़ीकरण को उद्धृत करने के लिए "एक बार सभी तर्कों को खिलाया गया है, तो आप प्रारूप ऑब्जेक्ट को स्ट्रीम में डंप कर सकते हैं। [...] परिणाम स्ट्रिंग प्रारूप ऑब्जेक्ट में तब तक पहुंच योग्य रहती है जब तक कि कोई अन्य तर्क पारित न हो जाए, उस समय इसे फिर से शुरू किया जाए। " दूसरा '%' वास्तव में प्रारूप को फिर से शुरू करता है, लेकिन यह मेरे मामले में एक अच्छी बात होनी चाहिए! – icecrime

+0

मेरे अनुभव में यह नहीं है, लेकिन यदि आपकी मिलेज भिन्न होती है तो मैं अपनी प्रतिक्रिया को अनदेखा करने का सुझाव देता हूं। कोई फर्क नहीं पड़ता कि आपकी समस्या और क्या हो सकती है। –

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