Shriramana Sharma wrote: > In my program, I would like QString-s (from Qt) to be automatically > converted to std::string-s. The Qt people could have done this by > providing an operator std::string () inside class QString but they > didn't so I tried to do this using a global operator. > > operator std::string (const QString & qs) { return qs.toStdString() ; } > > but I got: > > error: -Fʽoperator std::string(const QString&)ʼ must be a nonstatic member -A > function > > Whereas if I try: > > const QString operator+ (const std::string & ss, const QString & qs) { > return QString::fromStdString(ss) + qs ; > } > > it works. So what is special about operator othertype that it is not > allowed to be a non-member? My guess is that the decision to add this rule was to prevent the type-matching rules from becoming any more complex than they already are. Type conversion and assignment aren't like normal operators, as they can be invoked implicitly. Also, as overloaded functions are selected based upon the argument types, the interaction between type conversion and overloading can have non-obvious results. By requiring type conversion operators, constructors and assignment operators to be implemented as members, the behaviour of calling a method with arguments of pre-defined types is determined by the class alone. If any of those operators could be defined outside of the class, the behaviour would depend upon the presence or absence of such definitions. This could result in the class being implemented differently in different translation units, depending upon which other header files were included. > Similarly operator= is not allowed to be a non-member. So I cannot do: > > const std::string & operator= ( std::string & ss, const QString & qs ) { > ss = qs.toStdString() ; > return ss ; > } > > which is actually meaningful. Of course, since QString has toStdString, > I can always use that wherever I need to get a std::string from QString, > but operator overloading is a matter of convenience and I would like to > know if there is a strong reason that I cannot use operator othertype > and operator= as a non-member. > > It would enable me to define convenience > operators between objects of third-party (which includes the standard > library for me) types. Designing a language isn't just about whether or not a feature can be implemented, but also about whether it is a good idea. Many people (including myself) consider that the existence of implicit operators in C++ is a mistake, resulting in code which can be very hard to understand for anyone other than the author (or even for the author, once some time has elapsed since the code was written). Ensuring that you understand the evaluation of a particular expression requires exhaustive knowledge of any implicit operators which could be invoked. This is helped by the fact that such operators must appear somewhere in the definition of the relevant class (although, in the case of a conversion operator, it may be in a superclass; assignment operators aren't inherited). If such operators could be defined as global functions, you would have to hunt through all of the header files which are included in a translation unit to find any such operators (or to ensure that they didn't exist). -- Glynn Clements <glynn@xxxxxxxxxxxxxxxxxx> - To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html