Boost logo

Boost :

From: Markus Werle (numerical.simulation_at_[hidden])
Date: 2008-03-13 06:14:49


> [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));
}

 


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk