简体   繁体   English

C++ 仿函数行为

[英]C++ functors behavior

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;


struct cmp {
        bool operator()(const int& i, const int&  j) const{
            return false;
        }   
} ;

struct cmp2 {
        bool operator()(const int& i, const int&  j) const{
            return false;
        }   
} cmp2_item;


class Solution {
public:

    vector<int> smth(vector<int> arr, int k) {
        // nth_element(arr.begin(), arr.begin()+k, arr.end(), cmp); #ERROR
        // nth_element(arr.begin(), arr.begin()+k, arr.end(), cmp()); #WORKS
        // nth_element(arr.begin(), arr.begin()+k, arr.end(), cmp2_item); # WORKS
        // sort(arr.begin(), arr.end(), cmp); #ERROR
        // sort(arr.begin(), arr.end(), cmp()); #WORKS
        // set<int, cmp> s; # WORKS
        // set<int, cmp2_item> s; # ERROR
        return {};
    }
};

int main() {
    // your code goes here
    Solution s;
    s.smth({}, 1);
    return 0;
}

I want to understand why this code behaves in this way.我想了解为什么这段代码会以这种方式运行。

  • for nth_element we expect a functor so it makes sense to include like cmp(), but why does it start working without the (), when i instantiate the struct and use that?对于 nth_element,我们期望一个仿函数,因此包含类似 cmp() 是有意义的,但是当我实例化结构并使用它时,为什么它在没有 () 的情况下开始工作?
  • Similar in sort排序类似
  • while when using it for a comparator for a set, it only works if the struct is not instantiated and without the ()而当将它用于集合的比较器时,它仅在结构未实例化且没有 () 时才有效

Can someone please clarify using the signatures why this is so?有人可以使用签名澄清为什么会这样吗?

nth_element : template< class RandomIt, class Compare > void nth_element ( RandomIt first, RandomIt nth, RandomIt last, Compare comp ); nth_element : template< class RandomIt, class Compare > void nth_element ( RandomIt first, RandomIt nth, RandomIt last, Compare comp );

sort种类

  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp); 

set :设置

           class Compare = less<T>,        // set::key_compare/value_compare
           class Alloc = allocator<T>      // set::allocator_type
           > class set;

One part of this is that cmp2_item is not a type, its an instance of the type cmp2.其中一部分是cmp2_item不是类型,它是 cmp2 类型的实例。 So you can't pass that as a class type.因此,您不能将其作为 class 类型传递。 You might be able to do:你也许可以这样做:

    set<int, cmp> s; //# WORKS
    set<int, decltype(cmp2_item)> s2; //# NOW WORKS

For these:对于这些:

    // Not ok because cmp is not a function comparison object, its a type
    nth_element(arr.begin(), arr.begin()+k, arr.end(), cmp); #ERROR
    // Ok because this is effectively passing a functor (and not just a type) 
    // I believe this takes a copy of the functor type (by construction), I 
    // am not quite so clear on the inner workings of the compiler in this
    // case. I guess its by type comparison, but possible compiler
    // implementation specific?
    nth_element(arr.begin(), arr.begin()+k, arr.end(), cmp()); #WORKS
    // This is ok because it passes an actual comparison object (that has
    // operator () defined).
    nth_element(arr.begin(), arr.begin()+k, arr.end(), cmp2_item); # WORKS

Basically you have to look more closely at what you are passing: a type, an object or a function - and what the specific STL accepts as a parameter.基本上你必须更仔细地查看你传递的内容:一个类型,一个 object 或一个 function - 以及特定的 STL 接受什么作为参数。

Note:笔记:

comparison function object (ie an object that satisfies the requirements of Compare) which returns true if the first argument is less than (ie is ordered before) the second.比较 function object(即满足比较要求的 object)如果第一个参数小于(即在第二个之前排序)则返回 true。

See here: enter link description here请参阅此处:在此处输入链接描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM