⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 phoenix_users_manual.txt

📁 boost库提供标准的C++ API 配合dev c++使用,功能更加强大
💻 TXT
📖 第 1 页 / 共 5 页
字号:
We have seen the if_ statement. The syntax is:

    if_(conditional_expression)
    [
        sequenced_statements
    ]

[*3) if_ else_ statement:]

The syntax is

    if_(conditional_expression)
    [
        sequenced_statements
    ]
    .else_
    [
        sequenced_statements
    ]

Take note that else has a prefix dot and a trailing underscore: .else_

Example: This code prints out all the elements and appends " > 5", " == 5" or " < 5" depending on the element's actual value:

    for_each(c.begin(), c.end(),
        if_(arg1 > 5)
        [
            cout << arg1 << " > 5\n"
        ]
        .else_
        [
            if_(arg1 == 5)
            [
                cout << arg1 << " == 5\n"
            ]
            .else_
            [
                cout << arg1 << " < 5\n"
            ]
        ]
    );

Notice how the if_ else_ statement is nested.

[*4) while_ statement:]

The syntax is:

    while_(conditional_expression)
    [
        sequenced_statements
    ]

Example: This code decrements each element until it reaches zero and prints out the number at each step. A newline terminates the printout of each value.

    for_each(c.begin(), c.end(),
        (
            while_(arg1--)
            [
                cout << arg1 << ", "
            ],
            cout << val("\n")
        )
    );

[*5) do_ while_ statement:]

The syntax is:

    do_
    [
        sequenced_statements
    ]
    .while_(conditional_expression)

Again, take note that while has a prefix dot and a trailing underscore: .while_

Example: This code is almost the same as the previous example above with a slight twist in logic.

    for_each(c.begin(), c.end(),
        (
            do_
            [
                cout << arg1 << ", "
            ]
            .while_(arg1--),
            cout << val("\n")
        )
    );

[*6) for_ statement:]

The syntax is:

    for_(init_statement, conditional_expression, step_statement)
    [
        sequenced_statements
    ]

It is again almost similar to C++ for statement. Take note that the init_statement, conditional_expression and step_statement are separated by the comma instead of the semi- colon and each must be present (i.e. for_(,,) is invalid).

Example: This code prints each element N times where N is the element's value. A newline terminates the printout of each value.

    int iii;
    for_each(c.begin(), c.end(),
        (
            for_(var(iii) = 0, var(iii) < arg1, ++var(iii))
            [
                cout << arg1 << ", "
            ],
            cout << val("\n")
        )
    );

As before, all these are lazily evaluated. The result of such statements are in fact composites that are passed on to STL's for_each function. In the viewpoint of for_each, what was passed is just a functor, no more, no less.

[blurb __note__ Unlike lazy functions and lazy operators, lazy statements always return void.]

[page:1 Binders]

There are times when it is desireable to bind a simple functor, function, member function or member variable for deferred evaluation. This can be done through the binding facilities provided below. There are template classes:

# function_ptr ( function pointer binder )
# functor ( functor pointer binder )
# member_function_ptr ( member function pointer binder )
# member_var_ptr ( member variable pointer binder )

These template classes are specialized lazy function classes for functors, function pointers, member function pointers and member variable pointers, respectively. These are subclasses of the lazy- function class (see functions). Each of these has a corresponding overloaded bind(x) function. Each bind(x) function generates a suitable binder object.

Example, given a function foo:

    void foo_(int n) { std::cout << n << std::endl; }

Here's how the function foo is bound:

    bind(&foo_)

This bind expression results to a lazy-function (see functions) that is lazily evaluated. This bind expression is also equivalent to:

    function_ptr<void, int> foo = &foo_;

The template parameter of the function_ptr is the return and argument types of actual signature of the function to be bound read from left to right. Examples:

    void foo_(int);         ---> function_ptr<void, int>
    int bar_(double, int);  ---> function_ptr<int, double, int>

Either bind(&foo_) and its equivalent foo can now be used in the same way a lazy function (see functions) is used:

    bind(&foo_)(arg1)

or

    foo(arg1)

The latter, of course, follows C/C++ function call syntax and is much easier to understand. This is now a full-fledged lazy function that can finally be evaluated by another function call invocation. A second function call will invoke the actual foo function:

    int i = 4;
    foo(arg1)(i);

will print out "4".

Binding functors and member functions can be done similarly. Here's how to bind a functor (e.g. std::plus<int>):

    bind(std::plus<int>())

or

    functor<std::plus<int> > plus;

Again, these are full-fledged lazy functions. In this case, unlike the first example, expect 2 arguments (std::plus<int> needs two arguments lhs and rhs). Either or both of which can be lazily bound:

    plus(arg1, arg2)        // arg1 + arg2
    plus(100, arg1)         // 100 + arg1
    plus(100, 200)          // 300

A bound member function takes in a pointer or reference to an object as the first argument. For instance, given:

    struct xyz { void foo(int) const; };

xyz's foo member function can be bound as:

    bind(&xyz::foo)

or

member_function_ptr<void, xyz, int> xyz_foo = &xyz::foo;

The template parameter of the member_function_ptr is the return, class and argument types of actual signature of the function to be bound, read from left to right:

    void xyz::foo_(int);            ---> member_function_ptr<void, xyz, int>
    int abc::bar_(double, char);    ---> member_function_ptr<int, abc, int, double, char>

Take note that a member_function_ptr lazy-function expects the first argument to be a pointer or reference to an object. Both the object (reference or pointer) and the arguments can be lazily bound. Examples:

    xyz obj;
    xyz_foo(arg1, arg2)     // arg1.foo(arg2)
    xyz_foo(obj, arg1)      // obj.foo(arg1)
    xyz_foo(obj, 100)       // obj.foo(100)

Be reminded that var(obj) must be used to call non-const member functions. For example, if xyz was declared as:

    struct xyz { void foo(int); };  //  note non-const member function

the pointer or reference to the object must also be non-const since lazily bound arguments are stored as const value by default (see variable class in primitives).

    xyz_foo(var(obj), 100)      // obj.foo(100)

arg1..argN are already implicitly mutable. There is no need to wrap arg1..argN in a var. It is an error to do so:

    var(arg1)   //  ERROR! arg1 is already mutable
    var(arg2)   //  ERROR! arg2 is already mutable

Finally, member variables can be bound much like member functions. For instance, given:

    struct xyz { int v; };

xyz::v can be bound as:

    bind(&xyz::v)

or

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -