Re: operator for automatic type conversion not allowed as non-member

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Assembler]     [Git]     [Kernel List]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [C Programming]     [Yosemite Campsites]     [Yosemite News]     [GCC Help]

  Powered by Linux