boost::bind
为其占位符重载了多个运算符:
为方便起见,
bind
生成的函数对象会重载逻辑非运算符!
以及关系和逻辑运算符==
,!=
,<
,<=
,>
,>=
,&&
,||
。
例如,这允许我将_1 == desired_value
作为谓词传递给STL算法。
不幸的是,std::bind
似乎没有使这些运算符超载:(
为什么?
使用_1 == desired_value
模拟std::bind
有什么好的解决方法?
答案 0 :(得分:3)
IIRC,Boost.Bind只会占用占位符的那些运算符,因为原来的Boost Lambda库是Boost.Bind的改进版本(Boost.Bind已经过时了,这要归功于Boost.Phoenix,btw)。 std::bind
的占位符仅用于此目的,作为std::bind
参数的占位符。
作为一种解决方法,使用多态仿函数:
struct compare_equal{
template<class LHS, class RHS>
bool operator()(LHS&& lhs, RHS&& rhs){ // assume bool return
return std::forward<LHS>(lhs) == std::forward<RHS>(rhs);
}
};
// ...
auto bound = std::bind(compare_equal(), _1, desired_value);
答案 1 :(得分:0)
您可以自己为占位符重载这些运算符,例如operator<
:
struct less12
{
template<typename T, typename U>
bool operator()(const T& a, const U& b) const
{
return a < b;
}
};
less12 operator<(decltype(_1), decltype(_2))
{
return less12();
}
struct less21
{
template<typename U, typename T>
bool operator()(const U& b, const T& a) const
{
return a < b;
}
};
less21 operator<(decltype(_2), decltype(_1))
{
return less21();
}
template<typename T>
struct lessa1
{
const T& a;
template<typename U>
bool operator()(const U& b) const
{
return a < b;
}
};
template<typename T>
lessa1<T> operator<(const T& a, decltype(_1))
{
lessa1<T> result = {a};
return result;
}
template<typename U>
struct less1b
{
const U& b;
template<typename T>
bool operator()(const T& a) const
{
return a < b;
}
};
template<typename U>
less1b<U> operator<(decltype(_1), const U& b)
{
less1b<U> result = {b};
return result;
}
这是一个用法示例,与绑定器(自定义less12
vs std::less
)和lambda语法进行比较:
template<typename Iterator>
void quicksort(Iterator begin, Iterator end)
{
// ...
auto m = std::partition(begin + 1, end, _1 < *begin);
auto m = std::partition(begin + 1, end, std::bind(less12(), _1, *begin));
auto m = std::partition(begin + 1, end, std::bind(std::less<typename std::iterator_traits<Iterator>::value_type>(), _1, *begin));
auto m = std::partition(begin + 1, end, [begin](const typename std::iterator_traits<Iterator>::value_type& x) { return x < *begin; } );
// ...
}
真的期待N3421和多态lambda在这里:)
答案 2 :(得分:0)
std :: bind似乎没有超载这些运算符? 那是为什么?
因为C ++ 11添加了lambda,它提供了相同的(如果不是更好的话)方便来生成匿名仿函数对象。
使用std :: bind模拟_1 == desired_value有什么好的解决方法?
std :: bind不用于模拟行为。使用C ++ 11 lambdas来实现你的问题的答案:
std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), [](int i) -> bool { return i == desired_value; });
请注意,如果您使用可以派生返回类型的相当新的编译器,则不需要“ - &gt; bool”语法。
如果您不想或不能使用C ++ 11 lambdas,那么您可以创建一个非匿名仿函数,如下所示:
bool IsDesiredValue (int i) {
return (i == desired_value);
}
std::vector<int>::iterator i = std::find_if (myvector.begin(), myvector.end(), IsDesiredValue);
另一个例子,这里是使用C ++ 11 lambdas来创建一个匿名函子,用类型的值对向量进行排序:
std::sort(myVector.begin(), myVector.end(), [](const Foo& i, const Foo& j) -> bool { return i.myValue < j.myValue; });
另一种非lambda版本是:
struct myclass {
bool operator() (const Foo& i, const Foo& j) { return (i.myValue < j.myValue); }
} myobject;
std::sort(myVector.begin(), myVector.end(), myobject);
以下是使用boost的运算符重载进行相同排序的方法:
std::sort(myVector.begin(), myVector.end(), boost::bind(&MyClass::myValue, _1) < boost::bind(&MyClass::myValue, _2))
答案 3 :(得分:-1)
我认为这是因为C ++ 11有lambda,因此我不明白为什么你需要这样的运算符。