比较函数对象的类型签名

Type signature of comparison function object

如何在方法签名中使用比较函数对象类型?例如,这一切都很好:

struct compInt {
    bool operator() (const int a, const int b) { return a < b; }
};  

set<int,compInt> s1; 

// Actually this is no good, but removing it would obfuscate
// the accepted answer:
set<int> s2(compInt);  

[最后一个编译不过是函数声明,s2原来不是容器]

但我想这样做:

void func (____ x)
{
    set<int> s(x);
}

我不想这样做:

template<typename C>
void func (C& c)
{
    set<int> s(c);
}

function<bool(const int,const int)>不工作。我尝试将 compInt::operator() 设为虚拟,这样我就可以这样做:

void func (compInt& ci)

并传入派生对象,但实际上 set<int> s(ci) 无法编译(对此我非常感激,因为这是一个可怕的 hack)。

set<int> s1(compInt);

这声明了一个 return 类型为 set<int> 的函数。

set<int> s(x);

这声明了一个 set<int> 类型的局部变量。比较器类型不是从参数推导出来的,而是使用默认模板参数。因此,compInt 不用作比较器,因此您不能将 compInt 的实例传递给构造函数。

您可以使用:

void func (compInt x)
{
    std::set<int,compInt> s(x);

I tried making compInt::operator() virtual so I could do this:

void func (compInt& ci)

多态比较器会很成问题。 Set 按值存储对象,因此通过引用传递给函数无济于事。您需要使用类型擦除:定义一个包装器比较器,它将多态比较器作为构造函数参数,将其存储在动态存储中,并将调用运算符委托给存储的多态比较器。然后使用包装器类型作为集合的模板参数。

Eeroiki 让我朝着正确的方向前进。我最终确定的是这个(注意要比较的对象实际上不是整数,并且可以对它们应用各种比较器)。

using intCompFunc = std::function<bool(const int,const int)> 

struct compInt {
    intCompFunc comp;
    bool operator() (const int a, const int b) const {
        return comp(a, b);
}

void foo (intCompfunc icf)
{ 
    compInt ci { icf };
    std::set<int,compInt> s1(ci);
}    

这意味着用户可以传入任何类型的函子,例如。一个拉姆达:

foo([] (const int a, const int b) { return a < b; }); 

我的困惑源于为什么一开始不是这样,我认为这确实是一个历史问题(编写 STL 时还没有 C++11 仿函数)。 OTOH,使用基本类型而不是模板参数确实会引入一些运行时开销。