boost中是否有任何函数对象是std :: equal_to,std :: greater等系列函数对象的通用等价物?
基本上,std :: equal_to应该变成类似
的东西struct generic_equal_to
{
template <class T, class U>
bool operator()(const T& t, const U& u) const
{
return t == u;
}
};
我可以看到由于返回类型的问题,std :: plus等的泛型版本可能会更棘手(尽管decltype
可以解决这个问题)。但是我看不出为什么std :: equal_to函数对象本身应该需要模板参数的任何可能的原因。
肯定在某些地方有提升或STL这些版本存在吗?当然,编写它们是微不足道的,但我非常不喜欢复制库代码,特别是对于像这样显然微不足道的东西。
修改:
作为为什么我想要这个而不是使用lambdas或其他函数对象生成方法的一些上下文:
我正在编写一个通用的boost::fusion
序列比较函数:
template <class T>
bool sequence_equal(const T& left, const T& right)
{
return fusion::all(
fusion::zip(left, right),
fusion::fused<generic_equal_to>());
}
请注意fusion::fused<generic_equal_to>
部分,这会导致您无法按类型实际指定boost::lambda
或boost::phoenix
函数对象。我猜一个解决方案可能是decltype:
fusion::fused<decltype(_1 == _2)>()
这看起来很尴尬,甚至可能不起作用,具体取决于boost::lambda
或boost::phoenix
的实施方式 - 我真的不确定。
我知道你可以使用fusion::make_fused
解决这个问题,但是你必须实例化函数对象。我想到的解决方案是非模板equal_to
结构 - 我称之为generic_equal_to
。
我知道这是一个非常微不足道的问题 - 毕竟,make_fused(_1 == _2)
可能会内联到与fused<generic_equal_to>
相同的程序集。我无法相信boost或STL中没有generic_equal_to
函数对象,因此这个问题。
答案 0 :(得分:1)
我认为没有任何东西像你要求的那么直接,但是有些实用工具不仅涵盖了你的用例,而且超越了它。它们是Boost.Lambda和Boost.Phoenix(后者是lambda库的更通用的继承者)。
使用Boost.Lambda进行泛型相等的示例:
#include <boost/lambda/lambda.hpp>
#include <iomanip>
#include <iostream>
struct foo {};
bool operator==(foo, foo) { return true; }
bool operator==(foo, int) { return false; }
template <typename T, typename U, typename Func>
void f(const T& x, const U& y, Func func)
{
std::cout << func(x, y) << std::endl;
}
int main()
{
using namespace boost::lambda; // for placeholders
std::cout << std::boolalpha;
foo a, b;
int i = 0;
f(a, b, _1 == _2);
f(a, i, _1 == _2);
}
同样,凤凰城:
#include <boost/phoenix.hpp>
#include <iomanip>
#include <iostream>
struct foo {};
bool operator==(foo, foo) { return true; }
bool operator==(foo, int) { return false; }
template <typename T, typename U, typename Func>
void f(const T& x, const U& y, Func func)
{
std::cout << func(x, y) << std::endl;
}
int main()
{
using namespace boost::phoenix::arg_names; // for placeholders
std::cout << std::boolalpha;
foo a, b;
int i = 0;
f(a, b, arg1 == arg2);
f(a, i, arg1 == arg2);
}
这些中的每一个都可以扩展为以显而易见的方式支持其他运算符(更一般地,支持其他表达式)。我个人会和凤凰城一起去,因为如果你发现你需要比lambda提供更多的功能,你最终不会同时包含这两种功能。
答案 1 :(得分:0)
现在在C ++ 14中有std::equal_to<void>
(也可以用作std::equal_to<>
)
std::equal_to<>
是std::equal_to
的特化,其参数和返回类型已推断。
template< class T, class U>
constexpr auto operator()( T&& lhs, U&& rhs ) const
-> decltype(std::forward<T>(lhs) == std::forward<U>(rhs));
返回lhs和rhs之间的相等比较结果。