SSY
SSY

Reputation: 657

Why nested bind can defer evaluation of the expression

Item 34 in [Effective modern C++] gives an example that nested bind can defer evaluation of steady_clock::now() until setAlarm is invoked. std::chrono::steady_clock::now is actually a static member function. My understanding is that whenever it is passed as function argument, it will be evaluated.

Can anyone help to elaborate on why it can be deferred?

auto setSoundB =
    std::bind(setAlarm,
        std::bind(std::plus<>(), steady_clock::now(), 1h),
        _1,
        30s);

Upvotes: 6

Views: 425

Answers (1)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136246

In your example that call to steady_clock::now() is not deferred.

To prevent steady_clock::now() from evaluating now, wrap that in another bind call:

std::bind(&steady_clock::now)

E.g.:

auto mynow() {
    std::cout << "mynow\n";
    return std::chrono::steady_clock::now();
}

int main(int ac, char**) {
    std::cout << "creating a bind object\n";
    auto f = std::bind(std::plus<>(), mynow(), 1h);
    std::cout << "invoking bind object\n";
    f();


    std::cout << "\ncreating a bind object\n";
    auto g = std::bind(std::plus<>(), std::bind(&mynow), 1h);
    std::cout << "invoking bind object\n";
    g();
}

Outputs:

creating a bind object
mynow
invoking bind object

creating a bind object
invoking bind object
mynow

See std::bind for details:

Member function operator()

If the stored argument arg is of type T for which std::is_bind_expression<T>::value == true (for example, another bind expression was passed directly into the initial call to bind), then bind performs function composition: instead of passing the function object that the bind subexpression would return, the subexpression is invoked eagerly, and its return value is passed to the outer invokable object...

Upvotes: 7

Related Questions