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

标签 c++ templates generics boost stl

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/

相关文章:

java - 通配符泛型类型和泛型类型之间未经检查的转换

java - 从 <? 中检索子类型延伸动物>

java - 类型删除如何在 Java 中用于通配符?

c++ - 读取控制台调色板的 RGB 值

c++ - 为什么这个程序不能从 .bin 文件中正确读取(或写入?)? (C++)

c++ - 编译时 C++ 项目抛出错误 C2228,这不是预期的,因为控件在运行时未到达该点

C++ constexpr 类型 ID

c++ - NDEBUG 预处理器宏用于(在不同平台上)是什么?

c++ - 如何使用QtCreator远程调试图形应用程序?

c++ - 用于继承的模板便捷构造函数