Questions regarding lambda expressions
Hello, I am confused about why two certain lamba expressions work (on VC8) while two others do not. I do not profess to be any sort of expert in boost lambda expressions. This code is being executed in a function which is a friend of a template "takostack". Basically, this function deals with a member "contents_" that is a scoped_array of scoped_ptrs. It is supposed to iteratively call the << operator for the elements of contents_ scoped_array. template<typename O> std::ostream& operator<< (std::ostream& os, const takostack<boost::scoped_ptr<O> >& s) { /* Works, not sure why */ for (int i(0); i < s.top_; ++i) { os << *(&boost::scoped_ptr<O>::get, boost::lambda::_1)(s.contents_[i]) << " "; } /* Works, not sure why */ std::for_each(&s.contents_[0], &s.contents_[0] + s.top_, os << *(&boost::scoped_ptr<O>::get, boost::lambda::_1)(boost::lambda::_1) << " "); /* Does not work, don't know why std::for_each(&s.contents_[0], &s.contents_[0] + s.top_, os << *(boost::lambda::_1 ->* &boost::scoped_ptr<O>::get)(boost::lambda::_1) << " "); */ /* Does not work, don't know why std::for_each(&s.contents_[0], &s.contents_[0] + s.top_, os << *(boost::bind(&boost::scoped_ptr<O>::get, boost::lambda::_1)(boost::lambda::_1)) << " "); */ } Basically, I would like to understand why compilation succeeds without using bind, and fails when bind or the member pointer operator is used. The first failed example fails with: Error 131 error C2784: 'const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::other_action<Action>,boost::tuples::tuple<boost::lambda::lambda_functor<T>>>> boost::lambda::operator *(const boost::lambda::lambda_functor<T> &)' : could not deduce template argument for 'const boost::lambda::lambda_functor<T> &' from 'boost::lambda::detail::member_pointer_caller<RET,A,B>' d:\source\c\takostack\takostack\takostack.h 135 Error 132 error C2100: illegal indirection d:\source\c\takostack\takostack\takostack.h 135 Error 133 error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'boost::lambda::detail::member_pointer_caller<RET,A,B>' (or there is no acceptable conversion) d:\source\c\takostack\takostack\takostack.h 135 The second failed example fails with: Error 131 error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>' D:\Microsoft Visual Studio 8\VC\include\ostream 581 Thanks, Matt
Matyas W Egyhazy wrote:
Basically, I would like to understand why compilation succeeds without using bind, and fails when bind or the member pointer operator is used.
It would be nice if you could post a complete example so one could compile it as it is. I'm wondering why you call _1 on the functor in all, especially the last example. What's the derefenrencing for? Are you sure the first one works as you intend? Or does it merely compile? Jens
Jens, I have attached a full example now. I have included my questions and error snips from the compiler output within the source.
I'm wondering why you call _1 on the functor in all, especially the last example. Probably because I do not know what I am doing. I still get an error whether I do that or not. See attached example.
What's the derefenrencing for? Are you sure the first one works as you intend? Or does it merely compile? scoped_ptr<T>::get returns a T* so I dereference it before operator<< is called. The behavior works as intended, the operator<< for T is called.
Thanks, Matt #include <algorithm> #include <iostream> #include <vector> #include <string> #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <boost/scoped_ptr.hpp> #include <boost/scoped_array.hpp> using namespace std; using namespace boost; using namespace boost::lambda; int main(int argc, char** argv) { vector<char> t(10); scoped_array<scoped_ptr<int> > v(new scoped_ptr<int>[10]); //I know this is not typical to //initialize this way for (int k(0); k < 10; ++k) { v[k].swap(scoped_ptr<int>(new int(k))); } //Works fill(t.begin(), t.end(), 'b'); for_each(t.begin(), t.end(), cout << _1 << '\n'); /* Doesnt work? for_each(t.begin(), t.end(), cout << _1 << endl); Error 1 error C2784: 'std::basic_ostream<_Elem,_Traits> &std::operator <<(std::basic_ostream<_Elem,_Traits> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'std::basic_ostream<_Elem,_Traits> &' from 'const boost::lambda::lambda_functor<T>' d:\source\c\testlambda\testlambda\main.cpp 29 */ cout << endl; int q(0); //Works /* 0 1 2 3 4 5 6 7 8 9 */ for (int i(0); i < 10; ++i) { cout << *(v[i].get()) << endl; } cout << endl; //Doesnt work //for_each(&v[0], &v[0] + 10, cout << *bind(&scoped_ptr<string>::get, _1) << '\n'); /* Error 1 error C2665: 'boost::lambda::function_adaptor<Func>::apply' : none of the 2 overloads could convert all the argument types D:\boost_1_33_1\boost\lambda\detail\actions.hpp 87 */ //Doesnt work //for_each(&v[0], &v[0] + 10, cout << *bind(&scoped_ptr<string>::get, _1)(_1) << '\n'); /* Error 1 error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>' D:\Microsoft Visual Studio 8\VC\include\ostream 581 */ //Works, how does it know to bind correctly? /* 0 1 2 3 4 5 6 7 8 9 */ for_each(&v[0], &v[0] + 10, cout << *(&scoped_ptr<string>::get, _1) << '\n'); return 0; }
participants (2)
-
Jens Theisen
-
Matyas W Egyhazy