What's the meaning of this C++ struct?
I got a simple C++ struct开发者_StackOverflow中文版 as follows:
// Functor for peak to decreasing intensity sorting
struct cmp_decr_int2
{
bool operator() (peak2 a, peak2 b)
{
return a.int2 > b.int2;
}
};
is there an overload of the operator in this sample?
Yes. operator()
is called the "function call" operator, and allows an object to be usable as if it were a function. Such a class is called a "functor".
A common pattern is to make functors that compare two things for equality or relations, for use in anything requiring a comparison predicate. (This one could be usable in an std::map
, for example. It would have a member likecmp_decr_int2 compare;
and then it could compare the relation between two things with: if (compare(x, y)) /* x is less than y, by some metric */
)
This particular struct orders two peak2
's by comparing their int2
members. It could be better written as:
struct cmp_decr_int2
{
// note const! vvvvv
bool operator() (peak2 a, peak2 b) const
{
return a.int2 > b.int2;
}
};
The function should be const
because it does not need to change any members (there are none to change.) const
-correctness is important.*
In many cases these functors are used in contexts where the arguments themselves are const
, so you should either take the arguments by value as in the example or by constant reference.
You should prefer to pass types by const-reference over by-value, except when that type is fundamental (float, unsigned int, double, etc.) or smaller than a void*
. In most cases, then, you will pass by const-reference:
struct cmp_decr_int2
{
// note const&: vvvvv v vvvvv v vvvvv
bool operator() (const peak2 & a, const peak2 & b) const
{
return a.int2 > b.int2;
}
};
*If this were used as a predicate in a std::map
, for example, without const
the map wouldn't be able to compare two things while within a const
function.
Structs in C++ are just classes with a default accessor of public instead of private. So yes, that would have a function overload.
in c++ a struct is in every way like a class, except that the default parameter access is public:
rather than private:
. It is a common practice to use struct instead of class when the scope of the defined type's use is very narrow, such as in the example of a simple functor.
What this example does is emulate the appearance of a function pointer without the fragility of possibly being null.
The operator()
member here overloads function calling. when you try to do something like:
cmp_decr_int2 foo;
foo(peek2(), peek2());
that overload member gets called.
#include <iostream>
using namespace std;
struct cmp_decr_int2
{
bool operator() (int a, int b)
{
return a > b;
}
bool operator() (int i)
{
return i > 0;
}
};
int main()
{
cmp_decr_int2 a;
cout << a(1, 2) << endl;
cout << a(1) << endl;
}
Yep, sure can overload the function! This worked perfectly for me.
$13.5.4 states-
operator() shall be a non-static member function with an arbitrary number of parameters. It can have default arguments. It implements the function call syntax postfix-expression ( expression-listopt ) where the postfix-expression evaluates to a class object and the possibly empty expression-list matches the parameter list of an operator() member function of the class. Thus, a call x(arg1,...) is interpreted as x.operator()(arg1, ...) for a class object x of type T if T::operator()(T1, T2, T3) exists and if the operator is selected as the best match function by the overload resolution mechanism (13.3.3).
Therefore, the struct 'cmp_decr_int2' has definitely overloaded operator().
Note that this is also the only operator in C++ that can take variable number of arguments.
精彩评论