| Home | Libraries | People | FAQ | More

##### Object Transforms

The very first transform we looked at simply extracted the value of terminals. Let's do the same thing, but this time we'll promote all ints to longs first. (Please forgive the contrived-ness of the examples so far; they get more interesting later.) Here's the grammar:

    // A simple Proto grammar that matches all terminals,
    // and a function object that extracts the value from
    // the terminal, promoting ints to longs:
    struct ValueWithPomote
      : proto::or_<
            proto::when<
                proto::terminal< int >
              , long(proto::_value)     // <-- an "object" transform
            >
          , proto::when<
                proto::terminal< _ >
              , proto::_value
            >
        >
    {};

You can read the above grammar as follows: when you match an int terminal, extract the value from the terminal and use it to initialize a long; otherwise, when you match another kind of terminal, just extract the value. The type `long(proto::_value)` is a so-called object transform. It looks like the creation of a temporary long, but it's really a function type. Just as a callable transform is a function type that represents a function to call and its arguments, an object transforms is a function type that represents an object to construct and the arguments to its constructor.

| Note

Object Transforms vs. Callable Transforms

When using function types as Proto transforms, they can either represent an object to construct or a function to call. It is similar to "normal" C++ where the syntax `foo("arg")` can either be interpreted as an object to construct or a function to call, depending on whether `foo` is a type or a function. But consider two of the transforms we've seen so far:

    LeftmostLeaf(proto::_child0)  // <-- a callable transform
    long(proto::_value)           // <-- an object transform

Proto can't know in general which is which, so it uses a trait, `proto::is_callable<>`, to differentiate. `is_callable< long >::value` is false so `long(proto::_value)` is an object to construct, but `is_callable< LeftmostLeaf >::value` is true so `LeftmostLeaf(proto::_child0)` is a function to call. Later on, we'll see how Proto recognizes a type as "callable".