函数对象与函数指针

发布于 2024-09-04 09:49:50 字数 1238 浏览 3 评论 0原文

我有两个与函数对象和函数指针相关的问题,


问题:1

当我阅读STL的不同使用sort算法时,我看到第三个参数可以是函数对象,下面是一个示例

class State {  
  public:  
    //...
    int population() const;  
    float aveTempF() const;  
    //...  
};    
struct PopLess : public std::binary_function<State,State,bool> {  
    bool operator ()( const State &a, const State &b ) const  
        { return popLess( a, b ); }  
};  
sort( union, union+50, PopLess() );  

问题:

现在,语句 sort(union, union+50,PopLess()) 是如何工作的? PopLess() 必须解析为类似 PopLess tempObject.operator() 的内容,这与在临时对象上执行 operator () 函数相同目的。我认为这是将重载操作的返回值,即 bool (如我的示例中)传递给 sort 算法。

那么,在这种情况下,sort函数如何解析第三个参数呢?


问题 : 2

问题

与函数指针相比​​,使用函数对象有什么特别的优势吗?如果我们使用下面的函数指针会带来任何缺点吗?

inline bool popLess( const State &a, const State &b )
    { return a.population() < b.population(); }  
std::sort( union, union+50, popLess ); // sort by population

PS:以上参考文献(包括示例)均来自“Stephen C. Dewhurst”的《C++ Common Knowledge: Essential Intermediate Programming》一书。
我无法解码主题内容,因此发帖寻求帮助。

预先感谢您的帮助。

I have two questions related to function objects and function pointers,


Question : 1

When I read the different uses sort algorithm of STL, I see that the third parameter can be a function objects, below is an example

class State {  
  public:  
    //...
    int population() const;  
    float aveTempF() const;  
    //...  
};    
struct PopLess : public std::binary_function<State,State,bool> {  
    bool operator ()( const State &a, const State &b ) const  
        { return popLess( a, b ); }  
};  
sort( union, union+50, PopLess() );  

Question :

Now, How does the statement, sort(union, union+50,PopLess()) work? PopLess() must be resolved into something like PopLess tempObject.operator() which would be same as executing the operator () function on a temporary object. I see this as, passing the return value of overloaded operation i.e bool (as in my example) to sort algorithm.

So then, How does sort function resolve the third parameter in this case?


Question : 2

Question

Do we derive any particular advantage of using function objects versus function pointer? If we use below function pointer will it derive any disavantage?

inline bool popLess( const State &a, const State &b )
    { return a.population() < b.population(); }  
std::sort( union, union+50, popLess ); // sort by population

PS : Both the above references(including example) are from book "C++ Common Knowledge: Essential Intermediate Programming" by "Stephen C. Dewhurst".
I was unable to decode the topic content, thus have posted for help.

Thanks in advance for your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

朦胧时间 2024-09-11 09:49:50

PopLess() 实例化 PopLess 类的临时实例,并将其传递给 std::sort()。它实际上与您所说的相同(请注意,在本例中制作了额外的副本):

PopLess pl = PopLess();
sort(union, union + 60, pl);

然后,std::sort() 将调用 operator() 就那个例子而言。

至于函数对象还是函数指针哪个更好“更好”,这取决于情况。也许最重要的区别是函数对象可以维护状态,而通过指针传递的普通函数则不能。编译器可能能够更好地优化其中之一,但在大多数使用场景中这可能并不重要。

PopLess() instantiates a temporary instance of the class PopLess to be passed to std::sort(). It's effectively the same as if you were to say (note that in this example an extra copy is made):

PopLess pl = PopLess();
sort(union, union + 60, pl);

Then, std::sort() will call the operator() on that instance.

As for whether function objects or function pointers are better "better," it depends. Probably the most important difference is that function objects can maintain state while ordinary functions passed by pointer cannot. A compiler might be able to optimize one or the other better, but in most usage scenarios that's probably not important.

江挽川 2024-09-11 09:49:50

问题1:

PopLess() 必须解析为
类似于 PopLess > tempObject.operator() 这将是
与执行运算符 () 相同
在临时对象上运行函数。

它不是[如你所说的扩展]。 PopLess() 实际上是对隐式 PopLess::PopLess() 构造函数的调用。此代码创建一个临时对象并将其传递给函数调用中的第三个参数。

问题:2

我们有什么特别的优势吗
使用函数对象与
函数指针?

不是在这种情况下。这里你的 PopLess 对象是无状态的。您可以创建具有内部状态的函子(函数对象)。

示例:

struct ensure_min
{
    int value;
    ensure_min(int val) : value(val) {}
    int operator()(const int& i)
    {
        return std::max(value, i);
    }
}

std::vector<int>  values;
values.push_back(-1);
values.push_back(0);
values.push_back(1);
values.push_back(2);
values.push_back(3);

std::transform(values.begin(), values.end(), 
    std::ostream_iterator<int>(std::cout, "\n"), ensure_min(1));

此代码将输出序列中的所有数字,确保输出中的所有数字的最小值均为 1(如果原始数字小于,则输出为 1;如果原始数字小于,则输出为原始数字)大于或等于1)。

Question 1:

PopLess() must be resolved into
something like PopLess > tempObject.operator() which would be
same as executing the operator ()
function on a temporary object.

It's not [expanded as you said]. PopLess() is actually the call to the implicit PopLess::PopLess() constructor. This code creates a temporary object and passes it to the 3rd parameter in the function call.

Question : 2

Do we derive any particular advantage
of using function objects versus
function pointer?

Not in this case. Here your PopLess object is stateless. You can create functors (function objects) that have internal state.

Example:

struct ensure_min
{
    int value;
    ensure_min(int val) : value(val) {}
    int operator()(const int& i)
    {
        return std::max(value, i);
    }
}

std::vector<int>  values;
values.push_back(-1);
values.push_back(0);
values.push_back(1);
values.push_back(2);
values.push_back(3);

std::transform(values.begin(), values.end(), 
    std::ostream_iterator<int>(std::cout, "\n"), ensure_min(1));

This code will output all the numbers in the sequence, ensuring all the numbers in the output have a minimal value of 1 (the output is either 1 - if the original number was any less - or the original number if the original number was greater than or equal to 1).

小巷里的女流氓 2024-09-11 09:49:50

Q1:PopLess() 构造一个 PopLess 类型的对象,并 sort 然后使用该对象使用 对范围内的元素进行排序运算符()

查看 for_each 函数可能会更容易,它可以像这样实现:

template <typename IterT, typename Function>
Function for_each( IterT first, IterT last, Function f ) {
    for( ; first != last; ++first )
        f(*first);

    return f;
}

所以基本上 for_eachsort 以及使用函数对象的函数,简单地获取函数对象的实例并调用其operator ()

Q2:当您使用函数对象而不是函数指针时,编译器可能能够通过内联来优化函数调用,这对于编译器处理函数指针来说可能并不那么直接。此外,函数对象可以具有状态。

Q1: PopLess() constructs an object of type PopLess and sort then uses this object to sort the elements in the range using the operator ().

Looking at the for_each function might be easier, it could be implemented like this:

template <typename IterT, typename Function>
Function for_each( IterT first, IterT last, Function f ) {
    for( ; first != last; ++first )
        f(*first);

    return f;
}

So basically for_each and sort, and functions using function objects, simply take an instance of your function object and call its operator ().

Q2: A compiler might be able to optimize away the function call by inlining when you are using a function object rather than a function pointer, this might not be as straight forward for the compiler to do with the function pointer. Also, a function object can have state.

哽咽笑 2024-09-11 09:49:50

我不确定问题 1 在问什么,但 PopLess() 是一个对象。在排序函数内,该对象调用其operator()方法来比较项目。

I'm not sure what Question 1 is asking, but PopLess() is an object. Inside the sort function, this object has its operator() method called to compare the items.

寄居人 2024-09-11 09:49:50
  • 问题1:PopLess()是一个临时对象。
  • 问题2:它可以让你
    “功能”有状态......你可以
    用任何东西初始化对象
    在它被用作之前你喜欢
    功能
  • Question 1: PopLess() is a temporary object.
  • Question 2: it allows your
    "function" to have state... you can
    initialize the object with whatever
    you like before it gets used as a
    function
日暮斜阳 2024-09-11 09:49:50

主要的实际区别是函子维持状态的能力。例如,在对多列数据进行排序时,函子可以获取有关排序依据的列、排序方向甚至排序规则(区分大小写等)的信息。

The main practical difference is the ability for a functor to maintain state. For example, sorting multi-column data the functor can have info on which column to sort by, the sort direction and even collation rules (case sensitivity etc.).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文