S
Scott Meyers
Consider the following program, which was sent to me by a colleague last
summer along with a question as to whether not1 and not2 were supposed
to work with bind:
#include <algorithm>
#include <array>
#include <functional>
#include <iostream>
using namespace std;
using namespace std:laceholders;
template<class FIter, class Fun, class Pred>
void for_each_if(FIter beg, FIter end, Fun f, Pred pred) {
while (beg != end) {
if (pred(*beg))
f(*beg);
++beg;
}
}
void f(int n) {
cout << n << "\n";
}
int main() {
array<int,4> a = {1,2,3,4};
for_each_if(a.begin(), a.end(), f, not1(bind2nd(modulus<int>(),2)));
// uses bind2nd and compiles
for_each_if(a.begin(), a.end(), f, not1(bind(modulus<int>(),_1,2)));
// uses bind and doesn't compile
}
The problem is that std::bind doesn't declare the typedefs that
std::not1 expects, notably argument_type. 20.8/2 says that std::bind's
return type is unspecified, but 20.8.9.1.2/3 says that it's a call
wrapper, and 20.8.1/3-6 say that call wrappers are function objects, and
20.8/5 says function objects taking 1 or 2 arguments have to offer
typedefs like argument_type. All this leads me to believe that not1 and
not2 should work with objects returned from std::bind (and also to
std::function objects) as long as they have arity 1 or 2. Is this valid
reasoning?
Thanks,
Scott
summer along with a question as to whether not1 and not2 were supposed
to work with bind:
#include <algorithm>
#include <array>
#include <functional>
#include <iostream>
using namespace std;
using namespace std:laceholders;
template<class FIter, class Fun, class Pred>
void for_each_if(FIter beg, FIter end, Fun f, Pred pred) {
while (beg != end) {
if (pred(*beg))
f(*beg);
++beg;
}
}
void f(int n) {
cout << n << "\n";
}
int main() {
array<int,4> a = {1,2,3,4};
for_each_if(a.begin(), a.end(), f, not1(bind2nd(modulus<int>(),2)));
// uses bind2nd and compiles
for_each_if(a.begin(), a.end(), f, not1(bind(modulus<int>(),_1,2)));
// uses bind and doesn't compile
}
The problem is that std::bind doesn't declare the typedefs that
std::not1 expects, notably argument_type. 20.8/2 says that std::bind's
return type is unspecified, but 20.8.9.1.2/3 says that it's a call
wrapper, and 20.8.1/3-6 say that call wrappers are function objects, and
20.8/5 says function objects taking 1 or 2 arguments have to offer
typedefs like argument_type. All this leads me to believe that not1 and
not2 should work with objects returned from std::bind (and also to
std::function objects) as long as they have arity 1 or 2. Is this valid
reasoning?
Thanks,
Scott