我想std::set
用自定义比较功能创建一个。我可以使用来将其定义为类operator()
,但是我想享受在其中使用lambda的能力,因此我决定在具有std::set
作为成员的类的构造函数的初始化列表中定义lambda函数。但是我无法获得lambda的类型。在继续之前,这里有一个例子:
class Foo
{
private:
std::set<int, /*???*/> numbers;
public:
Foo () : numbers ([](int x, int y)
{
return x < y;
})
{
}
};
搜索后,我发现了两种解决方案:一种是使用std::function
。只需将设置比较函数类型设置为be,std::function<bool (int, int)>
然后像我一样完全传递lambda即可。第二种解决方案是编写一个make_set函数,例如std::make_pair
。
解决方案1:
class Foo
{
private:
std::set<int, std::function<bool (int, int)> numbers;
public:
Foo () : numbers ([](int x, int y)
{
return x < y;
})
{
}
};
解决方案2:
template <class Key, class Compare>
std::set<Key, Compare> make_set (Compare compare)
{
return std::set<Key, Compare> (compare);
}
问题是,我是否有充分的理由选择一个解决方案而不是另一个解决方案?我更喜欢第一个,因为它利用了标准功能(make_set不是标准功能),但是我想知道:使用std::function
代码会使(潜在地)速度变慢吗?我的意思是,这是否会降低编译器内联比较函数的机会,还是应该足够聪明以使其表现出完全相同的行为,就像它是lambda函数类型而不是那样std::function
(我知道,在这种情况下,它不能是lambda类型,但您知道,我一般来说是问吗?
(我使用GCC,但是我想知道流行的编译器通常会做什么)
总结,在我得到很多答案之后:
如果速度至关重要,则最好的解决方案是使用带operator()
函子的类。编译器最容易优化和避免任何间接调用。
要使用C ++ 11功能进行维护,并获得更好的通用解决方案,请使用std::function
。它仍然很快(比函子慢一点,但可以忽略不计),您可以使用任何函数- std::function
,lambda和任何可调用对象。
还有一个使用函数指针的选项,但是如果没有速度问题,我认为std::function
更好(如果使用C ++ 11)。
有一个选项可以在其他地方定义lambda函数,但是随后您就无法从作为lambda表达式的比较函数中获得任何收益,因为您也可以将其作为一个类,operator()
并且定义的位置也不会成为set构造。
还有更多想法,例如使用委托。如果您想对所有解决方案进行更彻底的解释,请阅读答案:)