7

The C++1x standard has deprecated the old STL binder functions in favor of the more universal std::bind. However, it seems that std::not1 and std::not2 are not deprecated in favor of a universal std::not_ or something. The reality is that the <functional> part of the STL, prior to C++1x, was really cumbersome to work with due to 1) the lack of lambdas, 2) the fact that the binders and negation functors required a nested typedef argument_type, meaning they couldn't work with ordinary functions, and 3) the lack of variadic templates necessitated separate binder and negation functions depending on the number of arguments.

C++1x changed all of this, dramatically improving the usefulness of <functional>. But for some reason, C++1x seems to have improved everything except std::not1 and std::not2. Really, it would be nice to have a standard universal negate function, like:

template <class F>
class negation
{
    public:

    negation(F f) : m_functor(f) { }

    template <class... Args>
    bool operator() (Args&&... args) const
    {
        return (!m_functor(args...));
    }

    private:

    F m_functor;    
};

template <class F>
inline negation<F> not_(F f)
{
    return negation<F>(f);
}

This would of course deprecate std::not1 and std::not2 in the same way the old binders were deprecated.

Question(s): 1) I've looked through the C++1x draft, and don't see any mention of a universal negate function. Did I miss it? 2) Is there some compelling reason why they added a universal bind and deprecated the old binders, but failed to do the same for the negation functions?

Channel72
  • 24,139
  • 32
  • 108
  • 180
  • Is `` even useful, now that we have lambdas? – Marcelo Cantos Apr 06 '11 at 13:49
  • @Marcelo, sure it is. `std::bind` is very useful. – Channel72 Apr 06 '11 at 13:51
  • 1
    How so? @Howard's comment to [DeadMG's answer](http://stackoverflow.com/questions/5567342/unary-and-binary-negation/5567712#5567712) links to [another answer](http://stackoverflow.com/questions/1930903/bind-vs-lambda/4581747#4581747) that argues for bind, because lambdas don't do type inference. Frankly, however it convinces me of exactly the opposite. Using explicit types — `auto f = [](const char* a, float b) { cout << a << ' ' << b; };` — annoying as it is, is vastly better than the bind solution presented in that answer. How often do you think bind offers a superior solution? – Marcelo Cantos Apr 07 '11 at 03:04

2 Answers2

6
  1. You didn't miss it.

  2. Compelling reason? It depends on who you ask. The lack of this functionality was discussed, but not until very late in the process. Hmm... I can't find the paperwork on that at the moment, there may not be any.

The best solution for this (imho) is to add operator!() to bind. But by the time this came up, the committee was in no mood to add new features to C++11. Perhaps it will come in a technical report.

Oh, here's the paperwork:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3224.html#gb97

Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577
1

Effectively, if not officially, all of the old function object binding system is deprecated, since lambdas are a much superior solution. I find it more curious that they bothered to update bind and any of the rest of it at all.

Most likely, you will find that this is because the original boost::bind did not provide such a negate function, and all of the new TR1/C++0x binding mechanism is based on that, and nobody noticed that not was missing.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • 1
    The committee does not consider bind to be obsolete. Here's a good SO answer as to why: http://stackoverflow.com/questions/1930903/bind-vs-lambda/4581747#4581747 – Howard Hinnant Apr 06 '11 at 14:16
  • @Howard: I said "not officially", as in, I recognize that they are not deprecated by the committee. – Puppy Apr 06 '11 at 14:29
  • @Potatoswatter: Funny, I believe that I did. Did I say anything to the contrary? – Puppy Apr 06 '11 at 15:10
  • 2
    Yes, you said it was effectively deprecated and that answer is a counterexample. Sometimes I'll write a reusable functor and want to negate it in one case. Either way, `not_()` performs type deduction which lambdas cannot do. – Potatoswatter Apr 06 '11 at 15:19
  • 2
    @DeadMG: I chose my words carefully in my comment. Anyone who can read the standard (and you obviously have the skills to do so) can clearly see bind isn't deprecated. The information I'm giving is that there are no proposals to deprecate bind, and no one on the committee is talking about doing so. I personally asked one of the authors of lambda if we needed to deprecate or remove bind. The response was remarkably similar to the SO answer I linked to above. All that being said, we have very little experience with the combination of bind and lambda. Your view might prevail, or might not. – Howard Hinnant Apr 06 '11 at 15:39
  • @Howard: Formal or informal deprecation aside, how does the answer you linked to demonstrate the benefits of bind? The fact that parameters can't be auto is a straw man, since declaring explicit parameter types is still vastly superior to the bind solution presented. – Marcelo Cantos Apr 07 '11 at 03:09