2012-10-27 11 views
6

सबसे पहले, मेरे पिछले प्रश्न here की समानता के लिए क्षमा चाहता है, लेकिन मुझे नहीं लगता कि मैंने सही चीज़ से पूछा है।बूस्ट :: फ़्यूज़न :: वेक्टर को रनटाइम पर कैसे भरें?

मैं एक विधि है:

template <typename T> 
void some_method(T &t) 
{...} 

जो एक प्रकार fusion::vector<T1, T2, T3, ..., Tn> लेता रनटाइम पर निर्धारित किया जाना - जैसे एक कॉल में vector<int, double> और vector<int, double, int> दूसरे में।

int blah = 5; 
for(int i = 0; i<size(t); i++){ 
at_c<i>(t) = blah; 
} 

इस के बाद से at_c एक const उम्मीद काम नहीं करता:

मैं की तरह कुछ के साथ गतिशील इस सदिश भरना चाहते हैं।

मैंने अन्य सामानों की कोशिश की है (पिछले प्रश्न देखें) लेकिन अभी भी यह हासिल नहीं कर सकते कि इसे कैसे प्राप्त किया जाए।

किसी भी मदद की बहुत सराहना की! धन्यवाद।

+0

'blah' क्या है? एक सीधी फॉर-लूप कभी काम नहीं करेगा, क्योंकि 'ब्लाह' के प्रत्येक पुनरावृत्ति पर एक अलग प्रकार होना चाहिए (आपको एक पुनरावर्ती टेम्पलेट फ़ंक्शन लिखना होगा)। क्या आप इस तरह के कुछ उदाहरण प्रदान कर सकते हैं कि आप मूल्यों का प्रतिनिधित्व कर रहे हैं? – Mankarse

+0

मुझे लगता है कि जो मूल्य डाले जाएंगे उन्हें उचित प्रकार पर उचित रूप से डाला जाएगा। तर्क के लिए आप कल्पना कर सकते हैं कि 'ब्लाह' एक 'int' है। – arlogb

+0

वे _runtime_ पर निर्धारित नहीं होंगे, वे _compile-time_ पर निर्धारित किए जाएंगे। –

उत्तर

6

रूप @Mankarse सही ढंग से निर्दिष्ट आप:

#include <boost/fusion/algorithm.hpp> 
#include <boost/fusion/container.hpp> 

struct F { 
    F(int blah): blah(blah){} 
    template <typename T> 
    void operator()(T& t) const { 
     t = blah; 
    } 
    int blah; 
}; 

template <typename T> 
void some_method(T &t) 
{ 
    boost::fusion::for_each(t, F(6)); 
} 

int main() { 
    boost::fusion::vector<int, double, int> idi; 
    some_method(idi); 
    boost::fusion::vector<int, double> id; 
    some_method(id); 
} 

की कोशिश में for_each रहस्यमय नहीं रखना, यहाँ कुछ ज्यादातर बराबर कोड बजाय संख्यात्मक सूचकांक का उपयोग करता है fusionfor लूप में कंटेनर का उपयोग नहीं कर सकते हैं और ऐसा इसलिए है क्योंकि fusion कंटेनर tuple हैं और प्रत्येक तत्व के पास अलग-अलग प्रकार हो सकते हैं अन्य तत्व, fusion कंटेनर के माध्यम से पुनरावृत्त करने वाले सभी फ़ंक्शन वास्तव में कुछ फ़ंक्शन हैं और आमतौर पर template या अधिभारित फ़ंक्शंस के रूप में कार्यान्वित किए जाते हैं। इसलिए कंटेनर को vector से प्रारंभ करने के लिए आपके पास एकाधिक फ़ंक्शन (या केवल एक टेम्पलेट जो एकाधिक कक्षाओं या कार्यों में संकलित किया जाएगा) होना चाहिए, जिनके पास उस वेक्टर तक पहुंच है (या कम से कम vector और एक राज्य से एक इटरेटर वेरिएबल जो प्रत्येक कॉल के लिए बढ़ाया जा सकता है)।

1) को बढ़ावा देने :: संलयन :: गुना का उपयोग करें:: तो आप 2 विकल्प हैं

template< class StdIteratorT > 
struct initialize_fusion_container_from_std_iterator { 
    typedef StdIteratorT result_type; 

    template< class T > 
    StdIteratorT operator()(StdIteratorT i, T& val) { 
     val = *i; 
     return ++i; 
    } 
}; 
void use_fold_demo() { 
    int p1[] = {4, 5, 6}; 
    fusion::vector<int, double, int> fv; 
    std::vector<int> sv2(p1, p1 + _countof(p1)); 
    fusion::fold(fv, sv2.begin(), 
    initialize_fusion_container_from_std_iterator<std::vector<int>::iterator>()); 
} 

2) एक समारोह है कि रिकर्सिवली कंटेनर के अगले आइटम के साथ ही फोन लिखें (इस समारोह की वाक्य रचना है याद पुनरावर्ती कार्यों लेकिन जैसे कि यह बिल्कुल पुनरावर्ती नहीं है):

// this will be called when we reach end of the fusion container(FIBeginT==FIEndT) 
template< class FIBeginT, class FIEndT, class StdIteratorT > 
void set_fusion_iterator(FIBeginT b, FIEndT e, StdIteratorT i, boost::mpl::true_) 
{ 
} 
// this will be called when FIBeginT != FIEndT 
template< class FIBeginT, class FIEndT, class StdIteratorT > 
void set_fusion_iterator(FIBeginT b, FIEndT e, StdIteratorT i, boost::mpl::false_) 
{ 
    *b = *i; 
    set_fusion_iterator(fusion::next(b), e, ++i, 
     fusion::result_of::equal_to< 
      typename fusion::result_of::next<FIBeginT>::type, FIEndT >()); 
} 

void recursive_function_demo() { 
    typedef fusion::vector<int, double, int> my_fusion_vector; 

    int p1[] = {1, 2, 3}; 
    std::vector<int> sv1(p1, p1 + _countof(p1)); 
    fusion::vector<int, double, int> fv; 
    set_fusion_iterator(fusion::begin(fv), fusion::end(fv), sv1.begin(), 
     fusion::result_of::equal_to< 
      typename fusion::result_of::end<my_fusion_vector>::type, 
      typename fusion::result_of::begin<my_fusion_vector>::type>()); 
} 

आप दूसरे मामले को देखने के रूप में और अधिक जटिल है, लेकिन अगर आप अपने तर्क को समझने आप fusion कंटेनर के साथ कुछ भी कर के लिए इसका इस्तेमाल कर सकते हैं, इसलिए पसंद है सब तुम्हारा!!

3

आप boost::fusion::for_each इस्तेमाल कर सकते हैं:,

#include <boost/fusion/algorithm.hpp> 
#include <boost/fusion/container.hpp> 
#include <boost/fusion/sequence.hpp> 

template<typename T, int N, int End> 
struct some_method_impl { 
    void operator()(T& t) const { 
     int blah = 6; 
     boost::fusion::at_c<N>(t) = blah; 
     some_method_impl<T, N+1, End>()(t); 
    } 
}; 

template<typename T, int N> 
struct some_method_impl<T,N,N> { 
    void operator()(T& t) const {} 
}; 


template <typename T> 
void some_method(T &t) 
{ 
    some_method_impl<T,0,boost::fusion::result_of::size<T>::type::value>()(t); 
} 

int main() { 
    boost::fusion::vector<int, double, int> idi; 
    some_method(idi); 
    boost::fusion::vector<int, double> id; 
    some_method(id); 
} 
+0

यह बहुत उपयोगी है। असल में आप काफी सही हैं, हालांकि मुझे 'blah' के बारे में अधिक विशिष्ट होना चाहिए था ... यह एक 'वेक्टर ' है और मैं इस 'blah' से फ़्यूज़न :: वेक्टर तक एक मान मैप करना चाहता हूं। क्या यह आपके सुझाए गए तरीके से संभव है? – arlogb

+1

@arlogb: हां, [ज़िप] (http://www.boost.org/doc/libs/release/libs/fusion/doc/html/fusion/sequence/concepts/random_access_sequence.html) एक सेट के साथ अनुक्रम सूचकांक के बाद, और 'for_each' के दौरान वेक्टर में इंडेक्स में सूचकांक का उपयोग करें। – Mankarse

0

इस बारे में कैसे?

यह बूस्ट :: फ़्यूज़न :: for_each का उपयोग कर उपरोक्त मामले के समान है।

लेकिन तेजी से जब मैं ऊपर से < आकार (टी)।

उपयोग

main(){ 
    boost::fusion::vector<int,double,std::string,char> vec(9 ,2.2 ,"aaa" ,'b'); 
    std::cout << at_n_dynamic<double>(vec, 1) << std::endl; //=> 2.2 
} 

शरीर

#include <boost/fusion/include/vector.hpp>  
template<typename V> 
struct fusion_at_n_functor 
{ 
    mutable int i; 
    int n; 
    mutable V value; 
    fusion_at_n_functor(int _n):i(0),n(_n){} 
    void operator()(const V & t) const 
    { if(i==n){value=t;} i++;} 
    template<typename T> 
    void operator()(const T & t) const 
    { i++;} 
}; 

template <typename First,typename Last,typename AtN > void 
at_n_dynamic_fusion_impl(First i,Last last,AtN &atn,boost::mpl::true_){} 
template <typename First,typename Last,typename AtN > void 
at_n_dynamic_fusion_impl(First i,Last last,AtN &atn,boost::mpl::false_){ 
    if(atn.i == atn.n){atn(boost::fusion::deref(i));} 
    else{ 
    atn(boost::fusion::deref(i)); 
    at_n_dynamic_fusion_impl(boost::fusion::next(i),last,atn, 
      boost::fusion::result_of::equal_to< 
      typename boost::fusion::result_of::next<First>::type,Last> ());} 
} 

template <typename Ret,typename Sequence> Ret 
at_n_dynamic(Sequence & seq, int n){ 
    fusion_at_n_functor<Ret> atn(n); 
#if 0 
    // enabling this if is same to the above case of boost::fusion::for_each 
    boost::fusion::for_each(seq, atn); 
#else 
    // this recursion loop stop at n. but boost::fusion::for_each stop at last 
    at_n_dynamic_fusion_impl(boost::fusion::begin(seq),boost::fusion::end(seq) ,atn, 
     boost::fusion::result_of::equal_to< 
      typename boost::fusion::result_of::begin<Sequence>::type, 
      typename boost::fusion::result_of::end<Sequence>::type>());  
#endif 
    return atn.value;} 

इस बढ़ावा-प्रयोक्ताओं की प्रति मिलीलीटर है मेरी पोस्ट http://lists.boost.org/boost-users/2012/08/75493.php http://d.hatena.ne.jp/niitsuma/20120803/1343979718

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