gpt4 book ai didi

c++ - 通用等价于 std 函数对象

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:19:21 25 4
gpt4 key购买 nike

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 函数对象本身需要模板参数的任何可能原因。

这些版本肯定存在于 boost 或 STL 中的某个地方吗?当然,编写它们很简单,但我非常不喜欢复制库代码,尤其是对于像这样看似微不足道的东西。

编辑:

关于为什么我想要这个而不是使用 lambda 或其他函数对象生成方法的一些上下文:

我正在写一个通用的 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::lambdaboost::phoenix已实现 - 我真的不确定。

我知道你可以使用 fusion::make_fused要解决整个问题,但是您必须实例化函数对象。那么,我想到的解决方案是非模板 equal_to结构-我叫我的generic_equal_to .

我知道这是一个非常微不足道的问题 - 毕竟,make_fused(_1 == _2)可能会内联到与 fused<generic_equal_to> 大致相同的程序集.我简直不敢相信没有 generic_equal_to boost 或 STL 中任何地方的函数对象,因此出现了这个问题。

最佳答案

我认为没有什么比您要求的更直接,但有些实用程序不仅涵盖您的用例,而且还不止于此。他们是Boost.LambdaBoost.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);
}

和 Phoenix 一样:

#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);
}

这些中的每一个都可以以明显的方式扩展以支持其他运算符(更一般地,扩展到其他表达式中)。我个人会选择 Phoenix,因为如果您发现您需要的功能比 lambda 提供的更多,那么您最终不会同时包含两者。

关于c++ - 通用等价于 std 函数对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10067745/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com