I have a class
class Point
{
private:
int x; int y;
public:
Point(int a, int b):x(a),y(b){}
Point():Point(0,0){}
}
If I want to sort a vector of Points, shall I use a lambda:
std::sort(xSortedPoints.begin(), xSortedPoints.end(),
[](const cv::Point& p1In, const cv::Point& p2In) -> bool {
return (p1In.x < p2In.x);
});
or using a static function in the class:
std::sort(xSortedPoints.begin(), xSortedPoints.end(), xSorting);
where xSorting is defined and declared in the Point class as
static bool xSorting(const Point& p1In, const Point& p2In)
{
return (p1In.x < p2In.x);
}
Why shall I use lambda, or why not?
EDIT:
Because I need to sort in the two ways (by x and by y) I did not define the < operator.
Based on the comments and answers I need to say that I use this in an application that runs continuously, so the sorting is done a lot of times. So what is better to use in my case: static or lambdas? Lambdas are created every time the std::sort is used? If yes, than I think static is the best choice... No?
Lambdas are there for convenience and slick code.
If you prefer to use a static function you should do this. If you use it once consider a lambda.
To my knowledge there is no performance gain when using lambdas.
So either do a static function, put an in place lambda or define less than operator for the class.
Lambda would make the code more concise especially if it's a one-liner like in your case. On the other hand, I would think the static function approach would be prefered if it needs to or can be used in more than 1 place.
This is kind of opinion based but in short:
If it is short and not used often, use a lambda. Your example is short enough. If the function is long or complicated or used often, give it a name.
In this special case, you could think about overloading operator < for Point if it makes sense. Then, no third argument to sort would be required, but you have make sure that < does what the naive reader would expect.
Btw, you can omit the ->bool, the compiler will deduce it automatically.
I don't know if there is any performance issues here, and the answers you get are going to be of the type "IM(H)O ....", so here are my two cents:
In this case, lambda is good in the sense that it shows the person who is reading the code what you mean by comparing two points. Mathematically, 2D (or any higher dimensions for that matter) points don't form an ordered set, so a < operator will be confusing. Having a static function, friend, ... on the other hand puts the definition of the comparison too far from the usage and, again, might add to confusion as the reader has to scroll to the definition to see what you mean by comparing two points.
Related
Say for example I have a function that returns a value from a 2-dimensional array:
float get_2d_noise(const point& p)
{
return map2D[p.x][p.y];
}
The point is a class that I've defined as part of my library:
struct point
{
int x;
int y;
}
Aside from doing this:
template<typename T>
float get_2d_noise(const T& p)
{
return noisemap[p.x][p.y];
}
Is it possible to get the same effect? I.e., create get_2d_noise in such a way that anything with an x and y member will work? (preferably catching errors at compile time, rather than runtime).
You may cheat with generic lambda (c++14), so you don't use explicitly template:
auto get_2d_noise = [&](const auto& p) -> float
{
return map2D[p.x][p.y];
};
You could write a macro that takes the name of the type as parameter and then creates the desired function. Something like
CREATE_2D_NOISE_FOR(someType)
that gets expanded to
float get_2d_noise(const someType& p) {
return noisemap[p.x][p.y];
}
However, this is highly not recommended, as you loose all the expressiveness of templates and gain all the problems that come with macros.
One possibility woud be to be syntactically explicit about what youw want to do. You could create an interface IPoint or similar (which in C++ can be done using an abstract class) where you define getters for your data members, say GetX and GetY; then you could formulate your function as follows.
float get_2d_noise(const IPoint& p)
{
return noisemap[p.GetX()][p.GetY()];
}
That way, you would not have to use generics; instead, you would use inheritance. However, any type you would like to use with get_2s_noise would have to be derived from IPoint (and implement the getters in a meaningful way), but that seems to be what you are looking for.
Is it possible to get the same effect? I.e., create get_2d_noise in such a way that anything with an x and y member will work? (preferably catching errors at compile time, rather than runtime).
This is literally the entire point of the existence of templates: they were created in order to support generic programming in C++. So no, there isn't another way to write templates in C++ outside of writing templates.
I have a class from Gtk Library that represents a color(GdkColor)....i have written my own interval tree around it...
Basically, it associates different colors to different intervals...
Now,in my test case, once i do a query for interval,
i want to compare the output with the expected value.
typedef struct
{
GdkColor color;
}intervalMetaData;
struct intervalInfo
{
signed int low;
signed int high;
intervalMetaData _data;
};
metaData = _intervalTree.performQuery(BWInterval);
GdkColor red;
//red==metaData.color //throws an error
I cannot overload == for gdkColor since it is from gdk library.
Is there any other way i can get around this??
IF, and only if, you have all the information you need to determine the equality, it is no problem to define the function yourself:
//not sure what GdkColor contains, but if it is large pass by const &
bool operator==(GdkColor a, GdkColor b) {
//check equality here
return result;
}
operator== does not have to be a member function.
If you have no way of comparing two GdkColor instances, you cannot find out if they are equal. Dead simple. If the framework provides no method which allows you to determine equality it probably does so for a good reason. This would usually be something, where neither <,>,<=, >=, !=, == nor anything comparable are provided and access to the members which would define the equality relation is not possible at all. I can't remember wanting to implement an operator==, where this was the case. However, if you have to force the API to its limit to implement an equality-comparison, you should investigate why that is so.
The typical case where you would have no access would be a C library, which uses a typedef to make a struct opaque. However, if it was intended for you to manipulate the contents of the struct or compare them, the framework would provide either something like
xxx getInformationXXX(struct S) or a method int compare(struct S*, struct S*)
I am not familiar with GdkColor, but I assume, there is some publicly available information that allows you to determine if two instances are equal. You should consider putting this function into a namespace, just in case GdkColor ever implements operator== itself to help avoid disambiguation.
operator== should not be the member of the class (and, probably, does not need an access to private/protected part of it), so it can be overloaded.
You can create the derived class and overload just anything you want inside it.
The simplest thing is just a helper function, kind of isEqualTo(), without any overloading at all.
class C
{
struct S
{
T a;
T2 b;
.
.
.
T z;
};
int compute(S s[]);
}
So I need this compute() method to work on the structure S in on of two ways (runtime selectable).
One case is to estimate something on base of a, b and the other contents of structure S, excluding z.
Other times I need the exact same computations, but taking z instead (and in place of) a. They both are the same type and have the same meaning.
The structure S is exposed in the API and thus need to be stored in exactly this layout.
What would be an efficient (compute() is being called rather often) end elegant solution? bool parameter? enum parameter? Template parameter (if so, how to implement it)?
NOTES:
compute() is quite a long function, with selecting a or z happening exactly once
I'd use an enum. It's no more or less efficient than bool, but it may be more clear at the call site:
compute(s, UseAB);
compute(s, UseZB);
Instead of:
compute(s, false);
compute(s, true);
The template option is possible but probably not better; you should try the regular run-time way first. If you care a lot about performance, consider making compute() inline if it is short and simple.
I would just use bool parameter if these are the only two cases. Keep it simple. And document it properly.
Or you can have two methods computeA(S s) and computeZ(S s). In this case it is really about what you are comfortable with.
Which approach is the better one and why?
template<typename T>
struct assistant {
T sum(const T& x, const T& y) const { ... }
};
template<typename T>
T operator+ (const T& x, const T& y) {
assistant<T> t;
return t.sum(x, y);
}
Or
template<typename T>
struct assistant {
static T sum(const T& x, const T& y) { ... }
};
template<typename T>
T operator+ (const T& x, const T& y) {
return assistant<T>::sum(x, y);
}
To explain the things a bit more: assistant has no state it only provides several utility functions and later I can define template specialization of it to achieve a different behavior for certain types T.
I think for higher optimization levels these two approaches don't lead to different byte codes because anyway the assistant will optimized "away"...
Thanks!
It is usually not a question of run-time performance, but one of readability. The former version communicates to a potential maintainer that some form of object initialization is performed. The latter makes the intent much clearer and should be (in my opinion) preferred.
By the way, what you've created is basically a traits class. Take a look at how traits are done in the standard library (they use static member functions).
Since assistant is essentially a collection of free functions, I would go with the static approach (maybe even make the constructor private). This makes clear that assistant is not intended to be instatiated. Also, and this is only a wild guess, this may result in slightly less memory consumption, since no implicit this-pointer (and no instance of the class) is needed.
I'd use the object approach - it seems a bit more standard and similar to the way you pass functors to STL algorithms - it's also easier to extend by allowing parameters passed to the constructor of the assistant to influence the results of the operations etc. There's no difference but the object approach will probably be more flexible long term and more in sync with similar solutions you'll find elsewhere.
Why an object is more flexible? One example is that you can easily implement more complex operations (like average in this example) that require you to store the temporary result "somewhere" and require analyzing results from a couple invocations while still keeping the same "paradigm" of usage. Second might be you'd want to do some optimization - say you need a temporary array to do something in those functions - why allocate it each time or have it static in your class and leave hanging and waste memory when you can allocate it when it's really needed, re-use on a number of elements but then release when all operations are done and the destructor of the object is called.
There's no advantage to using static functions - and as seen above there are at least a few advantages to using objects so the choice is rather simple imho.
Also the calling semantics can be practically identical - Assistant().sum( A, B ) instead of Assistant::sum( A, B ) - there's really little reason to NOT use an object approach :)
In the first method an assistant has to be created while the second method consists of just the function call, thus the second method is faster.
2nd method is preferred, in this method, there is no strcutre "assistent" variable created and it is calling only required member function. I think it is little bit faster in execution than 1st method.
In the Boost Signals library, they are overloading the () operator.
Is this a convention in C++? For callbacks, etc.?
I have seen this in code of a co-worker (who happens to be a big Boost fan). Of all the Boost goodness out there, this has only led to confusion for me.
Any insight as to the reason for this overload?
One of the primary goal when overloading operator() is to create a functor. A functor acts just like a function, but it has the advantages that it is stateful, meaning it can keep data reflecting its state between calls.
Here is a simple functor example :
struct Accumulator
{
int counter = 0;
int operator()(int i) { return counter += i; }
}
...
Accumulator acc;
cout << acc(10) << endl; //prints "10"
cout << acc(20) << endl; //prints "30"
Functors are heavily used with generic programming. Many STL algorithms are written in a very general way, so that you can plug-in your own function/functor into the algorithm. For example, the algorithm std::for_each allows you to apply an operation on each element of a range. It could be implemented something like that :
template <typename InputIterator, typename Functor>
void for_each(InputIterator first, InputIterator last, Functor f)
{
while (first != last) f(*first++);
}
You see that this algorithm is very generic since it is parametrized by a function. By using the operator(), this function lets you use either a functor or a function pointer. Here's an example showing both possibilities :
void print(int i) { std::cout << i << std::endl; }
...
std::vector<int> vec;
// Fill vec
// Using a functor
Accumulator acc;
std::for_each(vec.begin(), vec.end(), acc);
// acc.counter contains the sum of all elements of the vector
// Using a function pointer
std::for_each(vec.begin(), vec.end(), print); // prints all elements
Concerning your question about operator() overloading, well yes it is possible. You can perfectly write a functor that has several parentheses operator, as long as you respect the basic rules of method overloading (e.g. overloading only on the return type is not possible).
It allows a class to act like a function. I have used it in a logging class where the call should be a function but i wanted the extra benefit of the class.
so something like this:
logger.log("Log this message");
turns into this:
logger("Log this message");
Many have answered that it makes a functor, without telling one big reason why a functor is better than a plain old function.
The answer is that a functor can have state. Consider a summing function - it needs to keep a running total.
class Sum
{
public:
Sum() : m_total(0)
{
}
void operator()(int value)
{
m_total += value;
}
int m_total;
};
You may also look over the C++ faq's Matrix example. There are good uses for doing it but it of course depends on what you are trying to accomplish.
The use of operator() to form functors in C++ is related to functional programming paradigms that usually make use of a similar concept: closures.
A functor is not a function, so you cannot overload it.
Your co-worker is correct though that the overloading of operator() is used to create "functors" - objects that can be called like functions. In combination with templates expecting "function-like" arguments this can be quite powerful because the distinction between an object and a function becomes blurred.
As other posters have said: functors have an advantage over plain functions in that they can have state. This state can be used over a single iteration (for example to calculate the sum of all elements in a container) or over multiple iterations (for example to find all elements in multiple containers satisfying particular criteria).
Start using std::for_each, std::find_if, etc. more often in your code and you'll see why it's handy to have the ability to overload the () operator. It also allows functors and tasks to have a clear calling method that won't conflict with the names of other methods in the derived classes.
Functors are basically like function pointers. They are generally intended to be copyable (like function pointers) and invoked in the same way as function pointers. The main benefit is that when you have an algorithm that works with a templated functor, the function call to operator() can be inlined. However, function pointers are still valid functors.
One strength I can see, however this can be discussed, is that the signature of operator() looks and behaves the same across different types. If we had a class Reporter which had a member method report(..), and then another class Writer, which had a member method write(..), we would have to write adapters if we would like to use both classes as perhaps a template component of some other system. All it would care about is to pass on strings or what have you. Without the use of operator() overloading or writing special type adapters, you couldn't do stuff like
T t;
t.write("Hello world");
because T has a requirement that there is a member function called write which accepts anything implicitly castable to const char* (or rather const char[]). The Reporter class in this example doesn't have that, so having T (a template parameter) being Reporter would fail to compile.
However, as far I can see this would work with different types
T t;
t("Hello world");
though, it still explicitly requires that the type T has such an operator defined, so we still have a requirement on T. Personally, I don't think it's too wierd with functors as they are commonly used but I would rather see other mechanisms for this behavior. In languages like C# you could just pass in a delegate. I am not too familiar with member function pointers in C++ but I could imagine you could achieve the same behaviour there aswell.
Other than syntatic sugar behaviour I don't really see the strengths of operator overloading to perform such tasks.
I am sure there are more knowingly people who have better reasons than I have but I thought I'd lay out my opinion for the rest of you to share.
Another co-worker pointed out that it could be a way to disguise functor objects as functions. For example, this:
my_functor();
Is really:
my_functor.operator()();
So does that mean this:
my_functor(int n, float f){ ... };
Can be used to overload this as well?
my_functor.operator()(int n, float f){ ... };
Other posts have done a good job describing how operator() works and why it can be useful.
I've recently been using some code that makes very extensive use of operator(). A disadvantage of overloading this operator is that some IDEs become less effective tools as a result. In Visual Studio, you can usually right-click on a method call to go to the method definition and/or declaration. Unfortunately, VS isn't smart enough to index operator() calls. Especially in complex code with overridden operator() definitions all over the place, it can be very difficult to figure out what piece of code is executing where. In several cases, I found I had to run the code and trace through it to find what was actually running.
Overloading operator() can make the class object calling convention easier. Functor is one of the applications of operator() overloading.
It is easy to get confused between Functor and user-defined conversion function.
Below 2 examples show the difference between
1. Functor
2. User-defined conversion function
1. Functor:
struct A {
int t = 0;
int operator()(int i) { return t += i; } // must have return type or void
};
int main() {
A a;
cout << a(3); // 3
cout << a(4); // 7 (Not 4 bcos it maintaines state!!!)
}
2. User-defined conversion function:
struct A {
int t = 3;
operator int() { return t; } // user-defined conversion function
// Return type is NOT needed (incl. void)
};
int main() {
cout << A(); // 3 - converts the object{i:3} into integer 3
A a;
cout << a; // 3 - converts the object{i:3} into integer 3
}