op!= out of op==?

A

Angel Tsankov

Why does the standard provide the following operator !=:

template<class T> bool operator!=(const T&, const T&);

instead of this one which is more generic:

template<class T1, class T2> bool operator!=(const T1&, const T2&);?
 
B

Bob Hairgrove

Why does the standard provide the following operator !=:

template<class T> bool operator!=(const T&, const T&);

instead of this one which is more generic:

template<class T1, class T2> bool operator!=(const T1&, const T2&);?

Think: "apples and oranges" ... do you really want to compare them?
 
T

TB

Angel Tsankov skrev:
Why does the standard provide the following operator !=:

template<class T> bool operator!=(const T&, const T&);

instead of this one which is more generic:

template<class T1, class T2> bool operator!=(const T1&, const T2&);?

What? Are you saying that the following code shouldn't compile?

class A {};
class B {};

template<typename T1, typename T2>
bool operator!=(T1 const &, T2 const &) {
return true;
}

int main(int argc, char* argv[])
{
A() != B();
B() != B();
return 0;
}
 
K

Kai-Uwe Bux

Bob said:
Think: "apples and oranges" ... do you really want to compare them?

Sure, what's the problem: no apple is identical to any orange (unless your
oranges derive from your apples or vice versa, that is).


Best

Kai-Uwe Bux
 
A

Angel Tsankov

Bob Hairgrove said:
Think: "apples and oranges" ... do you really want to compare them?

Well, it's a little bit more complicated:

ptr< int const > p = get_ptr( ); // get_ptr( ) returns ptr< int > which is cast to ptr< int const > via a conversion operator;
p == get_ptr( ); // return value is of type ptr< int > and cannot be comapred to ptr< int const > "out of the box" since conforming
compilers may not take into account any conversions when making the list of callable funcions;

I'd also like to mention that I find it useful to design some templates so that they may be specialized for const types, e.g.:

ptr< int const > - this is a pointer to a constant of type integer; the pointer object may or may not be changed to point to another
constant of type integer, but the pointee may not be changed;
ptr< int > - this is a pointer to an integer; the pointee may be changed but the pointer object may or may not be changed depending
on its const-ness;
 
P

Peter_Julian

| Why does the standard provide the following operator !=:
|
| template<class T> bool operator!=(const T&, const T&);
|
| instead of this one which is more generic:
|
| template<class T1, class T2> bool operator!=(const T1&, const T2&);?
|

Think about the humongous requirements and exceptions required to provide
that generic template above when you consider the zillions of possible
combinations.

Why should the standard impose rules to restrict what a programmer should do
if T1 is a std::string and T2 is a const char* for example? Imagine if the
standard where to dictate what is defined if T1 is a user-type and T2 is an
unsigned integer? A pure-virtual class and a pointer? Shall i go on?

The purpose of the standard is not to complicate life. Its job is to provide
you, the programmer, which as much wiggle-room as possible to
provide/overload an operator like the one you dream of using your own rules
with the least amount of restrictions.

All the standard says is that x == y and !(x != y) must be equivalent. What
you do beyond that is not the standard's business.

Which becons me to ask: Whats preventing you from providing one?
 
A

Angel Tsankov

Angel Tsankov said:
Well, it's a little bit more complicated:

ptr< int const > p = get_ptr( ); // get_ptr( ) returns ptr< int > which is cast to ptr< int const > via a conversion operator;
p == get_ptr( ); // return value is of type ptr< int > and cannot be comapred to ptr< int const > "out of the box" since
conforming compilers may not take into account any conversions when making the list of callable funcions;

More precisely, I'm talking about the case when the name of the function to be called is the name of a function template.
 
K

Kodt

Angel said:
Well, it's a little bit more complicated:

ptr< int const > p = get_ptr( ); // get_ptr( ) returns ptr< int > which is cast to ptr< int const > via a conversion operator;
p == get_ptr( ); // return value is of type ptr< int > and cannot be comapred to ptr< int const > "out of the box" since conforming
compilers may not take into account any conversions when making the list of callable funcions;

I'd also like to mention that I find it useful to design some templates so that they may be specialized for const types, e.g.:

ptr< int const > - this is a pointer to a constant of type integer; the pointer object may or may not be changed to point to another
constant of type integer, but the pointee may not be changed;
ptr< int > - this is a pointer to an integer; the pointee may be changed but the pointer object may or may not be changed depending
on its const-ness;

For this particular case (and for similar cases), of course, you can
define a comparsion operator as follows

template<class T1, class T2>
bool // or, more strict, boost::enable_if< boost::is_same<const T1,
const T2>, bool >::type
operator == (ptr<T1> p1, ptr<T2> p2)
{ return p1.get() == p2.get(); }
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,434
Messages
2,571,691
Members
48,796
Latest member
Greg L.

Latest Threads

Top