Purpose of overloading operators in C++? - c++

What is the main purpose of overloading operators in C++?
In the code below, << and >> are overloaded; what is the advantage to doing so?
#include <iostream>
#include <string>
using namespace std;
class book {
string name,gvari;
double cost;
int year;
public:
book(){};
book(string a, string b, double c, int d) { a=name;b=gvari;c=cost;d=year; }
~book() {}
double setprice(double a) { return a=cost; }
friend ostream& operator <<(ostream& , book&);
void printbook(){
cout<<"wignis saxeli "<<name<<endl;
cout<<"wignis avtori "<<gvari<<endl;
cout<<"girebuleba "<<cost<<endl;
cout<<"weli "<<year<<endl;
}
};
ostream& operator <<(ostream& out, book& a){
out<<"wignis saxeli "<<a.name<<endl;
out<<"wignis avtori "<<a.gvari<<endl;
out<<"girebuleba "<<a.cost<<endl;
out<<"weli "<<a.year<<endl;
return out;
}
class library_card : public book {
string nomeri;
int raod;
public:
library_card(){};
library_card( string a, int b){a=nomeri;b=raod;}
~library_card() {};
void printcard(){
cout<<"katalogis nomeri "<<nomeri<<endl;
cout<<"gacemis raodenoba "<<raod<<endl;
}
friend ostream& operator <<(ostream& , library_card&);
};
ostream& operator <<(ostream& out, library_card& b) {
out<<"katalogis nomeri "<<b.nomeri<<endl;
out<<"gacemis raodenoba "<<b.raod<<endl;
return out;
}
int main() {
book A("robizon kruno","giorgi",15,1992);
library_card B("910CPP",123);
A.printbook();
B.printbook();
A.setprice(15);
B.printbook();
system("pause");
return 0;
}

It doesn't ever have to be used; it's just a convenience, a way of letting user-defined types act more like built-in types.
For example, if you overload operator<<, you can stream books the same way as integers and strings:
cout << "Book #" << n << " is " << books[n] << endl;
If you don't, you'd have to write the same thing like this:
cout << "Book #" << n << " is ";
books[n].printbook();
cout << endl;
Similarly, if you create a Fraction class and give it an operator+, you can use fractions the same way you use integers, and so on.
It's sometimes a tough design choice whether your class should act like a native type in one way or another (for example, does string's operator+ make sense?), but the point is that C++ gives you the choice.

Overloading the << operator allows your objects to be written out to the output in a way you specify, when passed to cout.
Otherwise, cout would just write out the address to your object.

The purpose of overloading operators is mostly syntactic sugar. It makes ugly stuff look nice.
But it's also about unifying interfaces, and an important reason for unifying interfaces is polymoprphism, in this case especially with templates.
Imagine we have a lovely complex number class Complex, and we want to have a Taylor series approximation of sine that we want to make work for Complex and double types.
If we support operator overloading on *, =, / etc. then we can write it like this:
template<typename T>
T sin(T t)
{
T t2 = t*t;
return t*(1 - t2/6 + (t2*t2)/120 );
}
If we cant have overloading on *, / etc. then it starts to get ugly, as we need a helper class to unify the interface for doubles and Complex, heres what it might look like. (I'm still allowing overloading of operator=, otherwise it gets even worse).
template<typename T>
T sin(T t)
{
T t2 = helper<T>::mult( t, t );
T t4 = helper<T>::mult( t2, t2 );
T s(1);
helper<T>::sincrement( &s, -1./6, t2);
helper<T>::sincrement( &s, -1./120, t4);
return helper<T>::mult( t, s );
}
template<>
struct helper<double>
{
static double mult( double a, double b) { return a*b; }
static void sincrement( double * v, double s, double x) { *v += s*x; }
}
template<>
struct helper<Complex>
{
static Complex mult( Complex a, Complex b ) { return a.mult(b); }
static void sincrement( Complex * v, double s, Complex x ) { v->add( x.scale(s) ); }
}
Now I know operator overloading can be ugly, and can hide what's really happening, but used correctly I think that it makes cases like this much easier to understand.

Overloading operators allows a special case of polymorphism.
The best example I can think of is a string class with the + operator overloaded.
In this case the operator would be overloaded to concatenate strings instead of "adding" two strings which doesn't make any sense.
To answer your question specifically overloading operators can (in some cases) produce more readable and maintainable code. However, what "makes sense" for one person may not make sense for the person maintaining the code.

You could easily use a member function instead, it just provides a "syntactic sugar" in most cases. For example in some languages adding 2 strings does a concat.
stringOne = stringOne + stringTwo;
Though it could easily be implemented with a member function like
stringOne.concat(stringTwo);

With an overloaded operator, you can use standard library algorithms which require that operator to be overloaded.
For example:
struct wtf{ wtf(int omg): omg(omg){} int omg; };
wtf operator+ (wtf const &omg, wtf const &lol)
{
return wtf(omg.omg+ lol.omg);
}
#include <iostream>
#include <numeric>
int main()
{
wtf lol[3]= { wtf(1), wtf(2), wtf(3) };
std::cout<< std::accumulate(lol, lol+ 3, wtf(0)).omg;
}
6

The thing about C++ is it passes objects by value, as a fundamental aim of how it works, and this really greatly changes how objects work compared to reference-semantics oriented languages like Java and Objective-C.
Whereas in one of those languages there is a clear distinction between primitive types and objects in terms of how you use them - that is, you copy primitives a lot, you stick them into expressions involving operators, that sort of thing, whereas your interaction with objects is mainly instantiating them, calling methods on them and passing the references to them into functions - in C++ you can use objects pretty much the same way as you use primitives. This brings up a lot of complicated issues that C++ programmers have to deal with, like object lifetimes, whether an object is an lvalue or rvalue (that is, if it has a lifetime outside the expression it appears in), etc.
One thing your question brings up is why a class would overload << and >>. The C++ standard library uses this convention for iostream classes, and highlights another big difference from reference-semantics based languages - in a value-semantics oriented language, class inheritance is inadequate to fully describe what you want to do with an object. We can loosely say that if an object overloads << and >> to stream data in and out of some resource, then it satisfies the concept of an iostream, even if it doesn't inherit from iostream, or ios_base, or something. The meaning of this is twofold:
If you put a value of this type into an expression and used <<, it would behave as expected.
If you instantiate a template with this type as a parameter, which calls operator<< on the object, the code will compile successfully.
I deliberately used the word concept above because there was going to be a feature in C++11 (it got postponed to the next version) called Concepts which would formalise this idea in the language. The situation we have now is a sort of duck typing - if a template wants to use a certain operator with a type, it will compile if the type provides that operator and won't if it doesn't, regardless of what the operator actually means. operator<< is a case in point - in its original meaning, for an integer type, it means "leftward signed bit-shift", but when you are using the concept of iostream, it means "stream data from the object on the right into the object to the left".

Your main purpose overloading the << and >> operators is to create an API in the spirit of the C++ standard library, so it becomes more natural for experienced C++ programmers to use your types.
It's so this way that the operators << and >> are known as insertion/extraction operators when used with the STL streams. From C they were just bit shift operators.
Since in the realm of standard C++ they acquired that meaning and even received new nomenclatures for that, It's aways good to reuse already established programming jargon.
Now, originally in the C++ creation, why it has gone this way for stream operations? by getting the shift operators and labeling them as insertion and extraction operators, I don't know, maybe a matter of taste to better express the idea of insertion/extraction given the appearance of the shift operators, a meaning which now, has become standard and suits to be reused.

Related

Is there a standard way to convert a class to a string

In Java, the standard is to define the method toString() to return a string representation of a class. Other than overloading operator<<, is there any such standard in C++? I know there are the std::to_string() methods to get a string representation of a number. Does the C++ standard speak of defining the method to_string() to serve similar purpose for a class, or is there a common practice followed by C++ programmers?
The standard way to do this kind of thing is to provide an insertion operator so that an object can be inserted into a stream -- which may be any kind of stream, such as a stringstream.
If you wish, you can also provide a method that converts to a string (useful for your insertion operator), and, if you find the conversion acceptable, you can provide a 'to string' operator.
Here's my standard 'point' class example:
template <typename T>
struct point
{
T x;
T y;
point(): x(), y() { }
point( T x, T y ): x(x), y(y) { }
};
template <typename T>
std::ostream& operator << ( std::ostream& outs, const point <T> & p )
{
return outs << "(" << p.x << "," << p.y << ")";
}
I also tend to keep a handy function around to convert things to strings:
template <typename T>
std::string to_string( const T& value )
{
std::ostringstream ss;
ss << value;
return ss.str();
}
Now I can use it easily:
int main()
{
point p (2,-7);
std::cout << "I have a point at " << p << ".\n";
my_fn_which_takes_a_string( to_string(p) );
You'll find that the Boost Lexical Cast Library is also designed for this kind of thing.
Hope this helps.
The C++ standard does not prescribe a way to do this but it looks like there is a proposal which may introduce such an option Generic to_string/to_wstring functions which says in the motivation section which also highlights the current common practices being taken(which I demonstrate below):
For a long time C++ programmers have been looking for an easy way to
convert an object into its string representation. A typical answer to
this problem was to create a local ostringstream, insert the object
into the stream, and then obtain the resulting string with the str
member function. This solution is simple, safe, flexible and
extensible, though definitely too verbose for something that rather
ought to be a single function call. C++11 provided (a partial)
solution in the form of a set of overloaded to_string/to_wstring
functions. Unfortunately, these are limited only to the built-in
numeric types. Non-standard solutions exist too – most notably
boost::lexical_cast, which offers two-way conversion of objects and
strings, but lacks any formatting control.
This paper proposes a solution that:
generalizes the existing to_string/to_wstring functions for any type that provides a stream output operator and for any basic_string
specialisation,
remains consistent and mostly compatible with these functions,
provides extra formatting and concatenation capabilities,
is conceptually simple by building upon the familiar ostringstream solution.
There are two trip reports STL's and Herb Sutter's and I don't see this paper mentioned in either. So hopefully this will be covered in the post-Kona mailing when it comes out.
The first method they mentioned in the proposal would look something like the example in this answer:
class A {
public:
int i;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.i << ")";
}
combined with the something similar to the example from here:
template <typename T>
std::string to_string(const T& value) {
std::ostringstream os;
os << value;
return os.str();
}
We can find a boost::lexical_cast example in the question Enabling Classes for Use with boost::lexical_cast.
Looks like there is no standard way. As I understand C++ standard does not permit overloading of std::to_string function.
I ended up using one of these two solutions:
Solution #1
Instead of toString() method you can use:
operator std::string() const {
return "Object string.";
}
And to support streams you can add something like this:
friend std::ostream & operator <<(std::ostream &out, const YourClass &obj) {
return out << static_cast<std::string>(obj);
}
I hope that the << operator will just inline the conversion from the first operator.
Solution #2
Or you can go other way if you think often in the stream-style:
friend std::ostream & operator <<(std::ostream &out, const YourClass &obj) {
out << "Object ";
out << "string.";
return out;
}
And use it inside conversion operator:
operator std::string() const {
std::ostringstream out;
out << *this;
return out.str();
}
Either way this get you covered for most of the cases.
Does the C++ standard speak of defining the method to_string() to serve similar purpose for a class,
No.
or is there a common practice followed by C++ programmers.
No. However, I suspect every project has similar functionality. The name and return type most likely depend on the coding guidelines of a project.
At my work, we use
virtual QString toString() const = 0;
in one of our base classes.
You can start using something similar for your project.
virtual std::string toString() const = 0;
in your base class(es).

C++ What is wrong with using a toString() method

I just came across this question which is about how to be able to print an object via
std::cout << x << std::endl;
As I understood, the standard way to accomplish this is to overload the ostreams << operator. However, this is adding a feature to the ostream rather than to my class.
The alternative (also given as answer to the above mentioned question) is to override the string conversion operator. However, this comes with the warning of leading to "unintentional conversions and hard-to-trace bugs".
Now i wonder if there are any drawbacks of writing a toString() method and then using it via
std::cout << x.toString() << std::endl;
Output streams handle output formatting as well as output. So with your toString() method clients won't be able to manage the formatting for the object the way they do for everything else:
// set specific formatting options for printing a value
std::cout << std::scientific << std::setprecision(10) << 10.0 << '\n'; // prints 1.0000000000e+01
// set formatting based on user's cultural conventions
std::cout.imbue(std::locale(""));
std::cout << 10000000 << '\n'; // depending on your system configuration may print "10,000,000"
Perhaps you don't care to allow any formatting so perhaps this won't matter.
Another consideration is that outputting to a stream doesn't require that the entire string representation be in memory at once, but your toString() method does.
Others have pointed this out, but I think a clearer way of saying it is that your classes interface is not limited to just the methods it provides, but also includes the other functions you build around it, including non-member functions such as the operator<< overloads you provide. Even though it's not a method of your class you should still think of it as part of your class's interface.
Here's an article that talks about this which perhaps you will find helpful: How Non-Member Functions Improve Encapsulation
Here's a simple example of overloading operator<< for a user defined class:
#include <iostream>
struct MyClass {
int n;
};
std::ostream &operator<< (std::ostream &os, MyClass const &m) {
for (int i = 0; i < m.n; ++i) {
os << i << ' ';
}
return os;
}
int main() {
MyClass c = {1000000};
std::cout << c << '\n';
}
As I understood, the standard way to accomplish this is to overload the ostreams << operator. However, this is adding a feature to the ostream rather than to my class.
And this is good thing. The smaller your class is the better. If popular C++ idiom allows you to have one more thing out of your class why not follow it?
Now i wonder if there are any drawbacks of writing a toString() method
The drawbacks are:
operator<< works in uniform way with builtin types (like int) and user-defined types. toString could be available for classes only
C++ is more heterogeneous than Java. std::string is the most popular string, but still there exist other string classes and they are used.
the string must be created, which potentially might come with a performance hit. If you write to stream directly you avoid it.
They are fundamentally different things. Providing a operator<< overload effectively extends the interface of the stream, making objects of your class type streamable. Providing a toString function extends the interface of your class, making it possible to get a std::string from your class. These represent different things.
The interface of your class should entirely correspond to what it represents in your program logic (single responsibility). Rarely is toString a natural part of a class's interface. However, extending the interface of the stream to accept more objects is much more logical.
That is, in one case you are saying "Now you can stream objects of this class type". In the other case you are saying "You can turn objects of this class type into a std::string." - it just so happens that that std::string is then streamable. Think about it - does it really make sense for my Person class to have a toString function? Since when have I been able to turn people into text?
Your first assumption is wrong. You don't need to make any changes in ostream.
An operator method like operator<< can be defined in two ways: As a method of the ostream class, taking your x object as a parameter, or as a plain old function with two parameters, taking an ostream as the first parameter, and your x object as the second parameter.
There is nothing wrong with a toString() function per class. It has the advantages of being more explicit, it can be made polymorph and it can be used in other situations than streaming, but you need to have a coding rule when working with a team ("was it to_string(), or str(), or streaming()?").
Overloading operator<< is more idiomatic. It just takes ostream as parameter and makes the conversion implicit when streaming, but since this is idiomatic in C++, most will expect an overloaded operator<< when seeing std::cout << x;.

Overloading operator << - C++

Background
I have a container class which uses vector<std::string> internally. I have provided a method AddChar(std::string) to this wrapper class which does a push_back() to the internal vector. In my code, I have to add multiple items to the container some time. For that I have to use
container.AddChar("First");
container.AddChar("Second");
This makes the code larger. So to make it more easier, I plan to overload operator <<. So that I can write
container << "First" << "Second"
and two items will get added to underlying vector.
Here is the code I used for that
class ExtendedVector
{
private:
vector<string> container;
public:
friend ExtendedVector& operator<<(ExtendedVector& cont,const std::string str){
cont.AddChar(str);
return cont;
}
void AddChar(const std::string str)
{
container.push_back(str);
}
string ToString()
{
string output;
vector<string>::iterator it = container.begin();
while(it != container.end())
{
output += *it;
++it;
}
return output;
}
};
It is working as expected.
Questions
Is operator overload written correctly?
Is it a good practice to overload operators in situations like this?
Will there be any performance issues or any other issues with this code?
Any thoughts?
Edit
After hearing the excellent comments, I decided not to overload << as it doesn't make sense here. I removed the operator overload code and here is the final code.
class ExtendedVector
{
private:
vector<string> container;
public:
ExtendedVector& AddChar(const std::string str)
{
container.push_back(str);
return *this;
}
.. other methods
}
This allows me to add
container.AddChar("First").AddChar("Second")
In C#, I can do this more easily by using the params keyword. Code will be like
void AddChar(params string[] str)
{
foreach(string s in str)
// add to the underlying collection
}
I know in C++, we can use ... to specify variable langth of parameters. But AFAIK, it is not type safe. So is it a recommended practice to do so? So that I can write
container.AddChar("First","Second")
Thanks for the replies.
Is operator overload written correctly?
It is, but one can do better. Like someone else mentioned, your function can be defined entirely out of existing, public functions. Why not make it use only those? Right now, it is a friend, which means it belongs to the implementation details. The same is true if you put operator<< as a member into your class. However, make your operator<< a non-member, non-friend function.
class ExtendedVector {
...
};
// note, now it is *entirely decoupled* from any private members!
ExtendedVector& operator<<(ExtendedVector& cont, const std::string& str){
cont.AddChar(str);
return cont;
}
If you change your class, you will not be sure that that your operator<< will still work. But if your operator<< entirely depends only on public functions, then you can be sure that it will work after changes were made to implementation details of your class only. Yay!
Is it a good practice to overload operators in situations like this?
As another guy said again, this is arguable. In many situations, operator overloading will look "neat" at first sight, but will look like hell next year, because you have no clue anymore what you had in mind when giving some symbols special love. In the case of operator<<, i think this is an OK use. Its use as an insertion operator for streams is well known. And i know of Qt and KDE applications that use it extensively in cases like
QStringList items;
items << "item1" << "item2";
A similar case is boost.format which also reuses operator% for passing arguments for placeholders in its string:
format("hello %1%, i'm %2% y'old") % "benny" % 21
It's of course also arguable to use it there. But its use for printf format specifies are well known and so its use is OK there too, imho. But as always, style is also subjective so take it with a grain of salt :)
How can i accept variable length arguments in a typesafe way?
Well, there is the way of accepting a vector if you are looking for homogeneous arguments:
void AddChars(std::vector<std::string> const& v) {
std::vector<std::string>::const_iterator cit =
v.begin();
for(;cit != v.begin(); ++cit) {
AddChar(*cit);
}
}
It's not really confortable to pass it though. You have to construct your vector manually and then pass... I see you already have the right feeling about the vararg style functions. One should not use them for this kind of code and only when interfacing with C code or debugging functions if at all. Another way to handle this case is to apply preprocessor programming. This is an advanced topic and is quite hacky. The idea is to automatically generate overloads up to some upper limit roughly like this:
#define GEN_OVERLOAD(X) \
void AddChars(GEN_ARGS(X, std::string arg)) { \
/* now access arg0 ... arg(X-1) */ \
/* AddChar(arg0); ... AddChar(arg(N-1)); */ \
GEN_PRINT_ARG1(X, AddChar, arg) \
}
/* call macro with 0, 1, ..., 9 as argument
GEN_PRINT(10, GEN_OVERLOAD)
That is pseudo code. You can have a look at the boost preprocessor library here.
Next C++ version will offer far better possibilities. Initializer lists can be used:
void AddChars(initializer_list<std::string> ilist) {
// range based for loop
for(std::string const& s : ilist) {
AddChar(s);
}
}
...
AddChars({"hello", "you", "this is fun"});
It's also possible in next C++ to support arbitrary many (mixed-type) arguments using variadic templates. GCC4.4 will have support for them. GCC 4.3 already partially supports them.
1) Yes, except since AddChar is public there's no reason it needs to be a friend.
2) This is arguable. << is sort of in the position of being the operator whose overloading for "weird" things is at least grudgingly accepted.
3) Nothing obvious. As always, profiling is your friend. You may want to consider passing the string parameters to AddChar and operator<< by const reference (const std::string&) to avoid unnecessary copying.
Is it a good practice to overload
operators in situations like this?
I don't think so. It's confusing as hell for someone who doesn't know that you've overloaded the operator. Just stick to descriptive method names and forget about the extra characters you're typing, its just not worth it. Your maintainer (or you yourself in 6 months) will thank you.
I'd prefer not to overload it that way personally because vectors don't normally have an overloaded left shift operator - it's not really it's idiom ;-)
I'd probably return a reference from AddChar instead like so:
ExtendedVector& AddChar(const std::string& str) {
container.push_back(str);
return *this;
}
so you can then do
container.AddChar("First").AddChar("Second");
which isn't really much bigger than bitshift operators.
(also see Logan's comment about passing strings in by reference instead of by value).
The operator overloading in this case is not good practice as it makes the code less readable. The standard std::vector doesn't have it either for pushing elements, for good reasons.
If you're worried about the caller code being too long, you could consider this instead of the overloaded operator:
container.AddChar("First").AddChar("Second");
This will be possible if you have AddChar() return *this.
It's funny that you have this toString() function. In that case, an operator<< to output to a stream would be the standard thing to use instead! So if you want to use operators make the toString() function an operator<<.
The operator is not correctly overloaded here. There is no reason to make the operator a friend since it can be a member of the class. Friend is for functions which are not actual members of the class (such as when overloading << for ostream so the object can be output to cout or ofstreams).
What you actually want the operator to be:
ExtendedVector& operator<<(const std::string str){
AddChar(str);
return *this;
}
It is usually considered bad practice to overload operators in a way that has them do something than they do normally. << is normally bit shift, so overloading it this way can be confusing. Obviously STL overloads << for "stream insertion" and so along with that it might make sense to overload it for your use in a similar way. But that doesn't seem like what you're doing, so you probably want to avoid it.
There are no performance issues since operator overloading is the same as a regular function call, just the call is hidden because it is done automatically by the compiler.
This is going to make things rather confusing, I would use the same syntax as std::cin into a variable:
std::cin >> someint;
"First" >> container;
This way it is at least an insertion operator. To me when anything has a << overloaded operator I expect it to be outputting something. Just like std::cout.

Encapsulate a simple type using C++ templates

I'm looking to add functionality to all the simple types in C++.
I want to write a single templated class that takes as a template parameter the type to be encapsulated and then has all the operators defined so that the encapsulated class works exactly as the simple type it encapsulates.
Something like this:
template <typename _SimpleType_>
class Attribute
{
public:
Attribute(_SimpleType_ value){ m_value = value; }
~Attribute(){}
// Cast
operator _SimpleType_() { return(m_value); }
// Comparisons
bool operator==(const a& other) const { return a == m_value; }
etc...
private:
_SimpleType_ m_value;
}
// Use like:
Attribute<int> i = 20;
while(i)
{
if((i & 0xF) == 0)
{
i >>= 2;
}
i--;
} etc...
The question is I'm sure there are a load of nuances that have to be dealt with and specialised template operators written; so is there anywhere that this has already been done so that I can just use that instead?
Boost is too large and complicated to put in my project but I can look at it for pointers if there is a class like this in there - whats its name if there is?
It's pretty simple, if tedious, - you just have to implement all the operators supported by the standard types and where the cast operator is not sufficient.
I have to ask though, why on earth are you trying to do this?
Here is an example of doing with an automatic typecast to T& (tested with GNU C++ 4.3.2):
#include <iostream>
using namespace std;
template <typename T>
class Attribute {
public:
Attribute(const T &value) { v = value; }
operator T & () { return v; }
private:
T v;
};
int main(int argc, char **argv)
{
Attribute<int> i(0);
i = 3;
i++;
i += 4;
i = i + 5;
i <<= 3;
cout << "i is now " << i << endl;
}
The C++ compiler casts automagically the reference to 'Attribute' to a reference to 'int' using the coercion operator 'operator T & ()'. So when the Attribute class does not provide the '++' operator or anything, the object is typecasted to int & and then the operator is looked up from there. Feel free to experiment.
You can get the implementation of the nonmutating operators for free, just by the conversion to _Simple_type_ (and you would get the assignments and increment/decrement by conversion to _Simple_type_&). Another question is whether this is really a good idea, as it creates conversions both T to Attribute<T> and Attribute<T> to T which causes problems while overloading - but you could fix that by making the constructor of Attribute<T> explicit.
This leaves the assignments and increment/decrement - you would just have to implement those.
Another possibility is using boost::operators - a header only library that facilitates creation of operator overloads based on algebraic rules. eg. you create operator+=, and it will provide you operator+. You create operator< and operator== and it will give you the other relationals etc.
Not to do with your question, but you should be aware that names such as _SimpleType_ (that is, names that begin with an underscore and an uppercase character) are reserved for the C++ compiler and Standard Libarary implementors to use - you are not allowed to use them in your own code.
I'm not sure if boost::ref is what you're looking for.
At any rate, the best thing you'd do is to just write it out by hand -- but this will start becoming a problem if you intend to support pointer and reference semantics.
What you'd also proabably need to do is put it in a namespace and implement the free function operator overloads and rely on ADL for it to get picked up. This will get a little unwieldy though as you implement more and more operators.
I like this form of encapsulation of simple types (original author - Sektor van Skijlen):
template<typename T>
class explicit_t
{
private:
T value;
template<typename V> explicit_t(V t);
public:
operator T&() {return value;}
explicit_t(const T& c) : value(c) {}
};
And the short example:
void fun(explicit_t<int> foo) {}
int main()
{
// fun('a');
// fun(3u);
// fun(3.0);
fun(4);
}
So what do I get? No more unwanted conversions.
You might also want to have a look at something more fancy - typegen.

Why override operator()?

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
}