| Home | Libraries | People | FAQ | More

##### Controlling Operator Overloads

By default, Proto defines every possible operator overload for Protofied expressions. This makes it simple to bang together an EDSL. In some cases, however, the presence of Proto's promiscuous overloads can lead to confusion or worse. When that happens, you'll have to disable some of Proto's overloaded operators. That is done by defining the grammar for your domain and specifying it as the second parameter of the `proto::domain<>` template.

In the Hello Calculator section, we saw an example of a Proto grammar, which is repeated here:

    // Define the grammar of calculator expressions
    struct calculator_grammar
      : proto::or_<
            proto::plus< calculator_grammar, calculator_grammar >
          , proto::minus< calculator_grammar, calculator_grammar >
          , proto::multiplies< calculator_grammar, calculator_grammar >
          , proto::divides< calculator_grammar, calculator_grammar >
          , proto::terminal< proto::_ >
        >
    {};

We'll have much more to say about grammars in subsequent sections, but for now, we'll just say that the `calculator_grammar` struct describes a subset of all expression types -- the subset that comprise valid calculator expressions. We would like to prohibit Proto from creating a calculator expression that does not conform to this grammar. We do that by changing the definition of the `calculator_domain` struct.

    // Define the calculator_domain. Expressions in the calculator
    // domain are wrapped in the calculator<> wrapper, and they must
    // conform to the calculator_grammar:
    struct calculator_domain
      : proto::domain< proto::generator< calculator >, calculator_grammar  >
    {};

The only new addition is `calculator_grammar` as the second template parameter to the `proto::domain<>` template. That has the effect of disabling any of Proto's operator overloads that would create an invalid calculator expression.

Another common use for this feature would be to disable Proto's unary `operator&` overload. It may be surprising for users of your EDSL that they cannot take the address of their expressions! You can very easily disable Proto's unary `operator&` overload for your domain with a very simple grammar, as below:

    // For expressions in my_domain, disable Proto's
    // unary address-of operator.
    struct my_domain
      : proto::domain<
            proto::generator< my_wrapper >
            // A simple grammar that matches any expression that
            // is not a unary address-of expression.
          , proto::not_< proto::address_of< _ > >
        >
    {};

The type `proto::not_< proto::address_of< _ > >` is a very simple grammar that matches all expressions except unary address-of expressions. In the section describing Proto's intermediate form, we'll have much more to say about grammars.