在C++中,greater_equal<double>的类型是否为function<bool(double,double)>?

3

我的理解是greater_equal<double>是一个函数对象,它的签名是function<bool (double, double)>,因此我尝试执行以下操作:

#include <functional>
#include <memory>

using namespace std;

int main() {
    std::shared_ptr<std::function<bool (double, double)>> f;
    auto f1 =make_shared<greater_equal<double>>();
    auto f2 = make_shared<less_equal<double>>();
    f = f1;
}

出乎我的意料,这段代码无法编译。错误信息如下:

'':无法将“const std::shared_ptrstd::greater_equal<double>”转换为“std::shared_ptr<std::function<bool(double,double)>>”

我不确定原因是什么。我的需求类似于上面的片段,我需要一个函数成员字段:std::shared_ptr<std::function<bool (double, double)>>,并且我需要根据某些条件分配<greater_equal<double>less_equal<double>。我应该如何实现这个要求?

有什么好惊讶的呢?这是一种重载了 operator() 的类型,它不能隐式转换为 std::function。如果你想要这样做,你需要一个 lambda。如果你知道实际的咒语,重载的运算符可能是可转换的,但对象本身不是 lambda。 - Tanveer Badar
@TanveerBadar 为什么它不能转换?它(是该类型的实例)。问题在于OP使用方式不正确。 - HolyBlackCat
@HolyBlackCat 那我就感到惊讶了。 :) 如果它应该是可转换的,那么这可能是 OP 正在使用的编译器的问题。或者也有可能是其他原因。 - Tanveer Badar
请注意,这里的问题出在shared_ptr上。您可以将std::greater_equal存储到std::function<bool(double, double)>中。但是在shared_ptr的构造/赋值中,您只能使用具有兼容指针的对象,而这不是您的情况。 - Daniel Langr
@TanveerBadar 因为std::function有相应的(非显式)转换构造函数,所以它是可转换的。您可以轻松编写std::function<bool(double, double)> f = std::greater_equal<double>{}; - Daniel Langr
如果你查阅,你会发现你对类型的假设是错误的。 - molbdnilo
1个回答

4
你所写的代码如果 std::greater_equal<double>std::less_equal<double> 继承自 std::function<bool(double, double)>,那么它是可用的。
但是由于 std::greater_equal<double>(和less_equal)的实例可以构造出 std::function<bool(double, double)>,你可以使用以下代码代替:
auto f1 = std::make_shared<std::function<bool(double, double)>>(std::greater_equal<double>{});

但我认为你一开始并不需要使用std::function

greater_equal<double>是一个函数对象,其签名为function<bool (double, double)>

是的,它的operator()接受(double, double)参数并返回bool,但它与 std :: function 无关。

std :: function 是一个包装类,可以存储任何它认为可调用的对象。它接受细微的签名变化(例如,即使 less/greater_equal 通过const引用接受参数,并且您告诉std :: function 参数应该按值传递,它仍然有效),并且可以存储带状态的对象(具有数据成员)。这些功能会带来开销


根据

我需要根据某些条件分配greater_equal<double>less_equal<double>

你不需要使用std :: function的这些特性。

相反,你可以使用函数指针(需要精确匹配签名,并且不能存储任何状态):

bool (*ptr)(double, double) = [](double a, double b)
{
    return a <= b;
};


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接