Allow "explicit" as a modifier for reference and pointer parameters

105 views
Skip to first unread message

Walt Karas

unread,
Feb 27, 2016, 4:36:55 PM2/27/16
to ISO C++ Standard - Future Proposals
This would block implicit conversion of a derived class reference/pointer to a base class reference/pointer.  One use would be to prevent the unexpected use of a comparison operator of a base class for an instance of a derived class.

Thiago Macieira

unread,
Feb 27, 2016, 6:28:17 PM2/27/16
to std-pr...@isocpp.org
On sábado, 27 de fevereiro de 2016 13:36:55 PST 'Walt Karas' via ISO C++
Polymorphic classes don't usually have comparison operators.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center

Nicol Bolas

unread,
Feb 29, 2016, 11:45:06 PM2/29/16
to ISO C++ Standard - Future Proposals


On Saturday, February 27, 2016 at 6:28:17 PM UTC-5, Thiago Macieira wrote:
On sábado, 27 de fevereiro de 2016 13:36:55 PST 'Walt Karas' via ISO C++
Standard - Future Proposals wrote:
> This would block implicit conversion of a derived class reference/pointer
> to a base class reference/pointer.  One use would be to prevent the
> unexpected use of a comparison operator of a base class for an instance of
> a derived class.

Polymorphic classes don't usually have comparison operators.

Equally importantly, I'm not sure why you would want to prevent such a use of a comparison operator if you provided one. The whole point of polymorphism is that you can treat the derived class as though it were the base class. So if your base class interface includes operator overloading, your derived class interface should behave in the same way. So it should be perfectly valid to compare a `Derived&` with a `Base&`, and to do so using the `operator<(Base&, Base&)` function by default.

If you find that problematic, odds are good that you're abusing polymorphism somewhere.

Nevin Liber

unread,
Feb 29, 2016, 11:53:56 PM2/29/16
to std-pr...@isocpp.org
You may wish to contact the author of n4475 and let him know your differing views on the subject, especially before it gets standardized.
--
 Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com>  +1-847-691-1404

Nicol Bolas

unread,
Mar 1, 2016, 12:20:03 AM3/1/16
to ISO C++ Standard - Future Proposals

Nothing in that paper conflicts with what I said.

Section 2.15 of that paper says: "If a class has a virtual function (directly or inherited), no == is generated." The OP is clearly talking about a polymorphic type, so that line applies: no `operator==` is generated. Therefore, the user must have provided such a function, in which case the usual rules for operator overloading apply.

What you're thinking about is probably the rest of 2.15, where it says that `b==a` doesn't work for the generated operator==. But note that the paper is very careful not to outlaw existing behavior. If you provide an `operator==` for the base class, `b==a` will still work, using the regular rules of C++. That is, 2.15 only outlaws it for generated operators.

Indeed, the entire paper goes through great pains to say that generated operators are not normal functions and do not partake in function overloading like regular functions.

Nevin Liber

unread,
Mar 1, 2016, 12:27:57 AM3/1/16
to std-pr...@isocpp.org
On 1 March 2016 at 00:20, Nicol Bolas <jmck...@gmail.com> wrote:

Nothing in that paper conflicts with what I said.

Really?  How about the other part of 2.15:

"Writing a good == for a class hierarchy is in general difficult and typically involves one or more virtual functions. For extra complications, compare objects of two different classes D1 and D2 derived from a common base B with a ==."

And yet you say:

The whole point of polymorphism is that you can treat the derived class as though it were the base class. So if your base class interface includes operator overloading, your derived class interface should behave in the same way. So it should be perfectly valid to compare a `Derived&` with a `Base&`, and to do so using the `operator<(Base&, Base&)` function by default.
 
If you find that problematic, odds are good that you're abusing polymorphism somewhere.

So, is it "in general difficult" or "abusing polymorphism" to provide a correct implementation of operator== for a base class?  It cannot be both.
-- 

Nicol Bolas

unread,
Mar 1, 2016, 9:46:57 AM3/1/16
to ISO C++ Standard - Future Proposals

Allow me to clarify my last sentence, with underlining to show the changed text:

If you find that allowing `operator<(const Base&, const Base&)` to be called on `Derived` instances to be problematic, odds are good that you're abusing polymorphism somewhere.

It's not having `operator<` for base classes that's abusing polymorphism. It's wanting to explicitly deny that operator's use on derived classes that suggests an abuse of polymorphism. And such denial is apparently one of the motivations for this idea.
Reply all
Reply to author
Forward
0 new messages