[proto] construct_: typos in docs and not able to get this to work

[calm down gmane erroneous top-post detector]
Hi! Having hard times to catch the ideas of the construct_ example. First of all: There are 2 typos in the definition of construct: // Define the construct() function template that // constructs an object lazily. template<typename T, typename A0, typename A1> // That one led to a lot of confuion // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // WRONG: typename proto::make_expr< typename proto::result_of::make_expr< proto::tag::function , construct_<T> const , A0 const & , A1 const &
::type const // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!VV!!!!!!!! // WRONG: construct(A0 const &a0, A0 const &a1) construct(A0 const &a0, A1 const &a1) { return proto::make_expr<proto::tag::function>( construct_<T>() , boost::ref(a0) , boost::ref(a1) ); }
To keep it off the other thread that I will continue later this day: Could you please remark in the docs with big red letters that make_expr is a type in namespace proto::functional and a function in namespace proto and why name clashes won't appear? I do not like that naming convention, mainly because I cannot remember the rules for the compiler for cases where both are visible. And yes, if you remember, I like to learn them again - now. Also for beginners like me it would be nice to have struct construct_ be renamed to constructor. The '_' is easily overlooked at midnight when you print 2 pages on one as I did. And that text is not for the faint-hearted anyway. Note that I'd prefer code repetition in this example: please add definitions for _1 and _2, better: a complete, compilable example, see next section: Trouble -------- Below is code that does not compile. I get the impression that this led to the confusion in the other thread: I cannot see how proto::eval drops in in the std::transform call. Please correct the code in order to make it work. Markus VC8: 1>------ Build started: Project: Learn_Proto_1, Configuration: Debug Win32 ------ 1>Compiling... 1>test_make_expr_2.cpp 1>using typeof emulation 1>d:\programme\microsoft visual studio 8\vc\include\algorithm(739) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'const boost::proto::exprns_::expr<Tag,Args>' (or there is no acceptable conversion) ---snip--- #include <iostream> #include <boost/proto/proto.hpp> #include <boost/proto/context.hpp> #include <boost/typeof/std/ostream.hpp> #include <algorithm> #include <vector> #include <map> using namespace boost; typedef std::pair<double, double> S; template <typename T> struct construct_ { typedef T result_type; T operator()() const { return T(); } template<typename A0> T operator()(A0 const &a0) const { return T(a0); } template<typename A0, typename A1> T operator()(A0 const & a0, A1 const & a1) const { return T(a0, a1); } }; // Define the construct() function template that // constructs an object lazily. template<typename T, typename A0, typename A1> typename proto::result_of::make_expr< proto::tag::function , construct_<T> const , A0 const & , A1 const &
::type const construct(A0 const &a0, A1 const &a1) { return proto::make_expr<proto::tag::function>( construct_<T>() , boost::ref(a0) , boost::ref(a1) ); }
// Define some placeholder types struct placeholder1 {}; struct placeholder2 {}; // Define the Proto-ified placeholder terminals proto::terminal< placeholder1 >::type const _1 = {{}}; proto::terminal< placeholder2 >::type const _2 = {{}}; int main() { // A lazy S constructor proto::terminal<construct_<S> >::type const construct_S = {{}}; // generate type information via compiler error // int i = construct_S; // Calls the lazy function and constructs an S proto::default_context ctx; S s = proto::eval( construct_S(1, 'a'), ctx ); //typedef proto::terminal<construct_<S> >::type c_t; // This does not work - WHY? // S s2 = construct<S>(_1, _2)(1, 'a'); std::vector<double> a, b; std::vector<S> buffer; std::transform(a.begin(), a.end(), b.begin(), std::back_inserter(buffer), construct<S>(_1, _2)); }

Hi Markus, Markus Werle wrote:
Having hard times to catch the ideas of the construct_ example.
First of all: There are 2 typos in the definition of construct:
<snip> Sorry for the typos! Thanks for catching them.
To keep it off the other thread that I will continue later this day:
Could you please remark in the docs with big red letters that make_expr is a type in namespace proto::functional and a function in namespace proto and why name clashes won't appear?
I do not like that naming convention, mainly because I cannot remember the rules for the compiler for cases where both are visible. And yes, if you remember, I like to learn them again - now.
If you bring them both into scope, the names will clash. There shouldn't be a need to ever bring the proto::functional namespace into scope, so there shouldn't be a problem. My approach to free functions in Proto is as follows: For each free function template proto::X, there is a class template proto::result_of::X which calculates the result type of proto::X. (Here I'm following existing practice established by Fusion.) There is also a class or class template proto::functional::X which is the function object equivalent of proto::X. These are provided as a convenience. I've had enough occasions to need them myself that I decided to provide them.
Also for beginners like me it would be nice to have struct construct_ be renamed to constructor. The '_' is easily overlooked at midnight when you print 2 pages on one as I did. And that text is not for the faint-hearted anyway.
Noted.
Note that I'd prefer code repetition in this example: please add definitions for _1 and _2, better: a complete, compilable example, see next section:
Yes, I'll build a complete example around this.
Trouble --------
Below is code that does not compile. I get the impression that this led to the confusion in the other thread: I cannot see how proto::eval drops in in the std::transform call. Please correct the code in order to make it work.
In the construct() section in the docs I say, "Making it work with std::transform() takes a little more effort, but that's covered in the Calc2 example," and I provide a link to the example. Getting std::transform() to invoke proto::eval() involves proto::extends<>, which I haven't talked about yet at that point. A better approach would be to provide a complete working construct() example and provide a link to that. In that spirit, I have added a Lambda example that shows a working construct() in action. HTH. -- Eric Niebler Boost Consulting www.boost-consulting.com

Eric Niebler wrote:
A better approach would be to provide a complete working construct() example and provide a link to that. In that spirit, I have added a Lambda example that shows a working construct() in action. HTH.
I forgot to mention that this example exposed a bug in MSVC which I had to work around. The latest proto.zip has the fix -- be sure to pick it up if you're using MSVC. -- Eric Niebler Boost Consulting www.boost-consulting.com
participants (2)
-
Eric Niebler
-
Markus Werle