What is this "operator" block of code in c++ class - c++

I'm using someone's class for bitmaps, which are ways of storing chess positions in 64-bit bitsets. I was wondering what the part with auto() operator does. Is "auto" used because it returns one bit, which is why a return-type isn't specified for the function? I get that it checks that x and y are in the bounds of the chess board, and asserts an error if they aren't. I also understand that it returns a bit that corresponds to the x,y value pair for the bitset. I also don't get why the function is defined like it is, with an extra pair of parentheses. Any help is appreciated!
class BitBoard {
private:
std::bitset<64> board;
public:
auto operator()(int x, int y) {
assert(0<=x && x<=7);
assert(0<=y && y<=7);
return board[8*y+x];
}
}
};

The "extra" pair of parentheses are because you're defining operator(), which lets instances of your class behave like functions. So if you had a:
BitBoard board;
you could get the value for x=3, y=5 by doing:
board(3, 5)
instead of having a method you call on the board explicitly, like board.get_bit_at(3, 5).
The use of auto just means it deduces the return type from std::bitset<64>'s operator[]; since the method isn't const qualified, this means it's just deducing the std::bitset::reference type that std::bitset's operator[] uses to allow mutations via stuff like mybitset[5] = true;, even though you can't give "true" references to single bits. If reimplemented a second time as a const-qualified operator(), e.g.:
auto operator()(int x, int y) const {
assert(0<=x && x<=7);
assert(0<=y && y<=7);
return board[8*y+x];
}
you could use auto again for consistency, though it doesn't save any complexity (the return type would be bool in that case, matching std::bitset's const-qualified operator[], no harder to type than auto).
The choice to use operator() is an old hack for multidimensional data structures to work around operator[] only accepting one argument; rather than defining operator[] to return a proxy type (which itself implements another operator[] to enable access to the second dimension), you define operator() to take an arbitrary number of arguments and efficiently perform the complete lookup with no proxies required.

operator() is the name of the function, which is then followed by another pair of parentheses listing the arguments. It is the function-call operator and overloading it allows you to make objects that act like functions/function pointers. In this case, it allows:
BitBoard thing;
thing(i, j); // looks like a function!
In this particular case, it's being used for indexing (like a[i]) but the subscript operator operator[] doesn't allow multiple indexes and the function-call operator does. So it was pretty common to see this for multi-dimensional arrays.
However, the new "preferred" style for multiple indexes in C++ is to pass a list to the subscript operator:
BitBoard thing;
std::cout << thing[{i, j}];
This would be accomplished by operator[](std::array<int, 2> xy).
But the author of this class has chosen the old way, that looks like a function call.
Overloaded operator() is also what makes lambda expressions tick inside.

Related

Calling Operator() "function call" to return reference to array element

I think I don't really understand what's behind references, and I'd be glad to learn more about those.
I'm writing a math "vector" Class to do basic linear algeabra for numerical simulation. I was using Eigen before i was convinced not to use external libraries anymore. My problem is pretty straightforward :
I declare vector and sets its 3 components of type Scalar (these are doubles). I can do math with my vectors as I overload operators, but this is beyond the scope of my question.
I want to access the i-th component of my object through the function call operator () as I was used with Eigen : myVector(0) = 0.0 ; or Scalar d = myVector(0)+1.0 ;
According to my understanding of references, this solution should be working :
class mtnVector {
public:
typedef double Scalar;
Scalar data [3];
(setters, math, etc...)
inline Scalar & operator() (const int i) const {
return data[i] ;
}
};
But g++ says that it doesn't like the way I implement it and comfirms I s*** at references :
Vector.h:185: error: invalid initialization of reference of type ?double&? from expression of type ?const double?
What's very strange from my point of view is that if the array containing the data is dynamically set (Scalar * data) (with new operator) at class construction, the code compiles fine. But I don't see the point of having dynamically set data holder.
I don't get neither the need of const to overload the function call operator but I accept it.
Your operator() is declared const. This means that calling the function should never end up modifying the object. That function returns a member of this object by non-const reference, which would allow whoever called operator() to modify the internals of the object. Obviously this would be silly, so the compiler just doesn't allow it. If you're going to return a reference to a member from a const member function, you need to make that reference const:
inline const Scalar& operator() (const int i) const {
return data[i] ;
}
You might want to provide both a const and non-const version of the function, one of which returns a const Scalar& and the other a Scalar& (this is how the standard library containers do it).
It seems strange that you'd want to use operator() for this. Your expression myVector(0) would look more natural as myVector[0], which you can achieve through overloading operator[] instead.
Also, you should ignore whoever convinced you that you shouldn't use external libraries. Eigen, in particular, is a very mature and thoroughly tested library. Unless you really have a good reason, you should be using it.

C++ STL sort() function, binary predicate

I have a piece of code that confuses me:
sort(data, data+count, greater<int>() );
it is a sort function in the C standard library. I am having trouble figuring out the meaning of the third argument. I have read that it is called a binary predicate. What does that mean and how can I make my own such predicate?
The third argument is called a predicate. You can think of a predicate as a function that takes a number of arguments and returns true or false.
So for example, here is a predicate that tells you whether an integer is odd:
bool isOdd(int n) {
return n & 1;
}
The function above takes one argument, so you could call it a unary predicate. If it took two arguments instead, you would call it a binary predicate. Here is a binary predicate that tells you if its first argument is greater than the second:
bool isFirstGreater(int x, int y) {
return x > y;
}
Predicates are commonly used by very general-use functions to allow the caller of the function to specify how the function should behave by writing their own code (when used in this manner, a predicate is a specialized form of callback). For example, consider the sort function when it has to sort a list of integers. What if we wanted it to sort all odd numbers before all even ones? We don't want to be forced to write a new sort function each time that we want to change the sort order, because the mechanics (the algorithm) of the sort is clearly not related to the specifics (in what order we want it to sort).
So let's give sort a predicate of our own to make it sort in reverse:
// As per the documentation of sort, this needs to return true
// if x "goes before" y. So it ends up sorting in reverse.
bool isLarger(int x, int y) {
return x > y;
}
Now this would sort in reverse order:
sort(data, data+count, isLarger);
The way this works is that sort internally compares pairs of integers to decide which one should go before the other. For such a pair x and y, it does this by calling isLarger(x, y).
So at this point you know what a predicate is, where you might use it, and how to create your own. But what does greater<int> mean?
greater<T> is a binary predicate that tells if its first argument is greater than the second. It is also a templated struct, which means it has many different forms based on the type of its arguments. This type needs to be specified, so greater<int> is the template specialization for type int (read more on C++ templates if you feel the need).
So if greater<T> is a struct, how can it also be a predicate? Didn't we say that predicates are functions?
Well, greater<T> is a function in the sense that it is callable: it defines the operator bool operator()(const T& x, const T& y) const;, which makes writing this legal:
std::greater<int> predicate;
bool isGreater = predicate(1, 2); // isGreater == false
Objects of class type (or structs, which is pretty much the same in C++) which are callable are called function objects or functors.
There is a class template called greater which needs a type argument. So you provide int as one. It became greater<int> and you create an instance of this class and pass it to the function as third argument.
Such an object is called function object or simply functor in C++, as the class overloads () operator. It's a callable entity. Its like this:
template<typename T>
struct greater
{
bool operator()(const T &a, const T &b)
{
//compare a and b and return either true or false.
return a > b;
}
};
If you create an instance of greater<int> and, say, the object is g, then you can write g(100,200) which evaluates to a boolean value, as the expression g(100,200) calls operator(), passing 100 as first argument and 200 as second argument, and operator() compares them and return either true or false.
std::cout << g(100,200) << std::endl;
std::cout << g(200,100) << std::endl;
Output:
0
1
Online demo : http://ideone.com/1HKfC
A binary predicate is any function/object that receives two objects (hence binary) and returns a bool (hence predicate); the idea is that it evaluates if the two objects satisfy some particular condition - in the example, if one is greater than the other.
You can create a predicate either by just defining a function with the correct signature
bool IsIntGreater(int First, int Second)
{
return First>Second;
}
and passing the name of the function as the argument (this will result in passing a function pointer), or creating a function object (a functor), i.e. an object which overloads the function call operator and thus can be used as a function; the std::greater<T> type is a template functor, and in your snippet a temporary object of type std::greater<int> is created and passed to the std::sort algorithm.
Functors have several advantages over functions, especially when they have to be passed as arguments, have a look here for more information about this.
See comp in http://www.cplusplus.com/reference/algorithm/sort/
It is the function that does the comparison.

C++ operator overloading, understanding the Google style guide

I am following a book to learn C++ (come from a python background). I've written this, which works:
class CatalogueItem
{
public:
CatalogueItem();
CatalogueItem(int item_code, const string &name, const string &description);
~CatalogueItem() {};
bool operator< (const CatalogueItem &other) const;
...
private:
...
};
...
list<CatalogueItem> my_list;
// this is just me playing around
CatalogueItem items[2];
items[0] = CatalogueItem(4, string("box"), string("it's a box"));
items[1] = CatalogueItem(3, string("cat"), string("it's a cat"));
my_list.push_back(items[0]);
my_list.push_back(items[1]);
my_list.sort();
The part I'm trying out is using the operator < to allow the list to sort itsself.
This all seems good, but http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Operator_Overloading seems to suggest avoiding doing this, which is exactly what the book says to do! ("In particular, do not overload operator== or operator< just so that your class can be used as a key in an STL container; instead, you should create equality and comparison functor types when declaring the container.")
I understand "create equality and comparison functor types" to mean creating comparison functions, like the below one:
bool my_comparison_function(const CatalogueItem &a, const CatalogueItem &b)
{
// my comparison code here
}
Is that what the style guide is referring to?
Does anyone have an option as to which method is more "correct"?
J
A functor type would be more like this:
struct CatalogueItemLessThan
{
bool operator()(const CatalogueItem &a, const CatalogueItem &b)
{
}
};
Then the usage would look like this:
list<CatalogueItem> my_list;
// this is just me playing around
CatalogueItem items[2];
items[0] = CatalogueItem(4, string("box"), string("it's a box"));
items[1] = CatalogueItem(3, string("cat"), string("it's a cat"));
my_list.push_back(items[0]);
my_list.push_back(items[1]);
my_list.sort(CatalogueItemLessThan());
The main advantage of this, is that is allows you to decouple sorting from the object itself. You can now provide as many types of sorting as you want, and use them in different places. (For example, string can be sorted in lexical order, or case-insensitively, or "naturally".
The advantage of using a functor as opposed to a loose function is that you can pass parameters into the comparison to modify how the functor should behave.
In general, the Google style-guide is not really the best style guide out there (IMHO especially their taking exception to exceptions, but that's another discussion). If an object has an obvious sorting order, I often add in a default operator<. If later, there are extra sort orders I want to add, then I add in loose functions. If at a later time, I need to add parameters to the sort order, then I make them into functors. There's no sense in adding in complexity before it's needed.
What Google is trying to say to you is the following.
As you know, you can overload one and only one operator '<' for a given type. Let's say it works for you. But imagine that in the future you might need to sort objects of the same type in accordance with some other comparison criterion. How are you going to do that? The only available version of '<' is already taken.
Of course, you can do that by writing a new named comparison function/functor (not the '<' operator) and explicitly supplying it to the sorting algorithm. You can write 2, 5, 10 more of them. You can write as many as you want. It will work. However, at that point there will be an obvious asymmetry in your code. One comparison function is implemented as 'operator <'. The others - as different named functions/functors. Is there a good reason for this asymmetry?
Well, there might be. If you have a very well-defined and obvious natural sorting method that applies to your type, it makes a very good sense to implement it as operator '<'. This would be the main comparison method. And other, auxiliary, less "natural" comparison methods can and should be implemented as named functions. This is prefectly fine.
However, what if you don't have such an obvious candidate for the "natural" comparison? In this case favoring one method over the other and "wasting" the '<' operator on an arbitrarily chosen one is not a good idea. In this case it is recommended to leave the '<' alone, and stick to named functions/functors instead.
In other words, by overloading the '<' you create a "favorite" comparison for the given type. If that's what you really want - go ahead and do it. But keep in mind that in many cases creating an artificial and arbitrary "favorite" is not a good idea. Don't rush the process of choosing that favorite. Don't take the '<' too early.
A functor type is a C++ type (class or struct), that overloads the () operator so that instances of the type behave like a function. This is similar to a class implementing __call__() in Python.
Some STL collection types like std::map require a key_compare functor to order the keys in interal tree structures and thus providing fast access times. By default, this is std::less, which uses operator< to compare values. Therefore this operator is often provided to allow custom classes to act as keys in std::map (and similar).
Google obviously discourages this in favor of supplying your own comparison functor. So, instead of implementing operator<, you could do the following:
struct my_compare
{
bool operator ()(const CatalogueItem& lhs, const CatalogueItem& rhs)
{
...
}
};
If you must access private members to implement this, declare the functor as a friend of your class.

Using stable_sort() to sort doubles as ints

I have a huge array of ints that I need to sort. The catch here is that each entry in the list has a number of other associated elements in it that need to follow that int around as it gets sorted. I've kind of solved this problem by changing the sorting to sort doubles instead of ints. I've tagged each number before it was sorted with a fractional part denoting that value's original location before the sort, thus allowing me to reference it's associated data and allowing me to efficiently rebuild the sorted list with all the associated elements.
My problem is that I want to sort the double values by ints using the function stable_sort().
I'm referring to this web page: http://www.cplusplus.com/reference/algorithm/stable_sort/
However, since I'm a new programmer, i don't quite understand how they managed to get the sort by ints to work. What exactly am i supposed to put into that third argument to make the function work? (i know i can just copy and paste it and make it work, but i want to learn and understand this too).
Thanks,
-Faken
Edit: Please note that I'm a new programmer who has had no formal programming training. I'm learning as i go so please keep your explanations as simple and as rudimentary as possible.
In short, please treat me as if i have never seen c++ code before.
Since you say you're not familiar with vectors (you really should learn STL containers ASAP, though), I assume you're playing with arrays. Something along these lines:
int a[] = { 3, 1, 2 };
std::stable_sort(&a[0], &a[3]);
The third optional argument f of stable_sort is a function object - that is, anything which can be called like a function by following it with parentheses - f(a, b). A function (or rather a pointer to one) is a function object; other kinds include classes with overloaded operator(), but for your purposes a plain function would probably do.
Now you have your data type with int field on which you want to sort, and some additional data:
struct foo {
int n;
// data
...
};
foo a[] = { ... };
To sort this (or anything, really), stable_sort needs to have some way of comparing any two elements to see which one is greater. By default it simply uses operator < to compare; if the element type supports it directly, that is. Obviously, int does; it is also possible to overload operator< for your struct, and it will be picked up as well, but you asked about a different approach.
This is what the third argument is for - when it is provided, stable_sort calls it every time it needs to make a comparison, passing two elements as the arguments to the call. The called function (or function object, in general) must return true if first argument is less than second for the purpose of sorting, or false if it is greater or equal - in other words, it must work like operator < itself does (except that you define the way you want things to be compared). For foo, you just want to compare n, and leave the rest alone. So:
bool compare_foo_n(const foo& l, const foo& r) {
return l.n < r.n;
}
And now you use it by passing the pointer to this function (represented simply by its name) to stable_sort:
std::stable_sort(&a[0], &a[3], compare_foo_n);
You need to pass the comparison function. Something like this:
bool intCompare(double first, double second)
{
return static_cast<int>(first) < static_cast<int>(second);
}
int main()
{
std::vector<double> v;
v.push_back(1.4);
v.push_back(1.3);
v.push_back(2.1);
v.push_back(1.5);
std::stable_sort(v.begin(), v.end(), intCompare);
return 0;
}
Inside the sort algorithm, to compare the values the comparison function passed by you is used. If you have a more complex data structure and want to sort on a particular attribute of the data structure then you can use this user-defined function to compare the values.
I believe you are talking about this function:
bool compare_as_ints (double i,double j)
{
return (int(i)<int(j));
}
And the function call:
stable_sort (myvector.begin(), myvector.end(), compare_as_ints);
The function compare_as_ints is a normal function but this is being passed to the stable_sort as a function pointer. i.e., the address of the function is being passed which would be used by stable_sort internally to compare the values.
Look at this function pointer tutorial if you are unclear about this.

Overloading operator [] for a sparse vector

I'm trying to create a "sparse" vector class in C++, like so:
template<typename V, V Default>
class SparseVector {
...
}
Internally, it will be represented by an std::map<int, V> (where V is the type of value stored). If an element is not present in the map, we will pretend that it is equal to the value Default from the template argument.
However, I'm having trouble overloading the subscript operator, []. I must overload the [] operator, because I'm passing objects from this class into a Boost function that expects [] to work correctly.
The const version is simple enough: check whether the index is in the map, return its value if so, or Default otherwise.
However, the non-const version requires me to return a reference, and that's where I run into trouble. If the value is only being read, I do not need (nor want) to add anything to the map; but if it's being written, I possibly need to put a new entry into the map. The problem is that the overloaded [] does not know whether a value is being read or written. It merely returns a reference.
Is there any way to solve this problem? Or perhaps to work around it?
There may be some very simple trick, but otherwise I think operator[] only has to return something which can be assigned from V (and converted to V), not necessarily a V&. So I think you need to return some object with an overloaded operator=(const V&), which creates the entry in your sparse container.
You will have to check what the Boost function does with its template parameter, though - a user-defined conversion to V affects what conversion chains are possible, for example by preventing there being any more user-defined conversions in the same chain.
Don't let the non-const operator& implementation return a reference, but a proxy object. You can then implement the assignment operator of the proxy object to distinguish read accesses to operator[] from write accesses.
Here's some code sketch to illustrate the idea. This approach is not pretty, but well - this is C++. C++ programmers don't waste time competing in beauty contests (they wouldn't stand a chance either). ;-)
template <typename V, V Default>
ProxyObject SparseVector::operator[]( int i ) {
// At this point, we don't know whether operator[] was called, so we return
// a proxy object and defer the decision until later
return ProxyObject<V, Default>( this, i );
}
template <typename V, V Default>
class ProxyObject {
ProxyObject( SparseVector<V, Default> *v, int idx );
ProxyObject<V, Default> &operator=( const V &v ) {
// If we get here, we know that operator[] was called to perform a write access,
// so we can insert an item in the vector if needed
}
operator V() {
// If we get here, we know that operator[] was called to perform a read access,
// so we can simply return the existing object
}
};
I wonder whether this design is sound.
If you want to return a reference, that means that clients of the class can store the result of calling operator[] in a reference, and read from/write to it at any later time. If you do not return a reference, and/or do not insert an element every time a specific index is addressed, how could they do this? (Also, I've got the feeling that the standard requires a proper STL container providing operator[] to have that operator return a reference, but I'm not sure of that.)
You might be able to circumvent that by giving your proxy also an operator V&() (which would create the entry and assign the default value), but I'm not sure this wouldn't just open another loop hole in some case I hadn't thought of yet.
std::map solves this problem by specifying that the non-const version of that operator always inserts an element (and not providing a const version at all).
Of course, you can always say this is not an off-the-shelf STL container, and operator[] does not return plain references users can store. And maybe that's OK. I just wonder.