Wednesday, January 27, 2016

Digest for comp.lang.c++@googlegroups.com - 25 updates in 6 topics

Christopher Pisz <nospam@notanaddress.com>: Jan 27 02:16PM -0600

I am having one of those "intellectual discussions" with a coworker whom
is making some bold sweeping claims about C++ and C#, which I have to
disagree with. It's lighthearted and for fun. I wonder what others say
on the topic.
 
He has put forth the following
 
Premise: Multiple inheritance is universally accepted as bad
Conclusion: Although the compiler allows you to, you should never use
multiple inheritance in C++
 
Premise: C# enforces an interface to contain no functionality or data in C#
Premise: The problems with multiple inheritance can be eliminated
because of the former premise.
Conclusion: Inheriting from an interface in C# "doesn't count" as
multiple inheritance and you _should_ do it
 
I have countered that "just because the compiler doesn't enforce"
something doesn't mean I "cannot" or "should not" do it in C++
 
Premise: I can create an interface in C++ the same as you can in C#
Premise: I can inherit from interfaces in the same manner as you can in C#
Conclusion: If you can do it I can too and, in fact, I should do it.
 
He disagrees with my final conclusion and I cannot for the life of me
fathom why.
 
Am I missing something? Do we need to explore a premise further?
What are your thoughts?
 
 
 
 
 
 
--
I have chosen to troll filter/ignore all subthreads containing the
words: "Rick C. Hodgins", "Flibble", and "Islam"
So, I won't be able to see or respond to any such messages
---
4ndre4 <4ndre4@4ndre4.com.invalid>: Jan 27 08:40PM

On 27/01/2016 20:16, Christopher Pisz wrote:
 
> I am having one of those "intellectual discussions" [...]
 
Rather than discussing in abstract terms, it would be nice to examine a
real case, where C# interfaces prove to be a better solution than C++
abstract classes, or vice versa. The only problem with mi that comes to
my mind is the classic diamond problem.
 
--
4ndre4
"The use of COBOL cripples the mind; its teaching should, therefore, be
regarded as a criminal offense." (E. Dijkstra)
Daniel <danielaparker@gmail.com>: Jan 27 12:51PM -0800

On Wednesday, January 27, 2016 at 3:16:36 PM UTC-5, Christopher Pisz wrote:
> because of the former premise.
> Conclusion: Inheriting from an interface in C# "doesn't count" as
> multiple inheritance and you _should_ do it
 
I think the experience of Java and C# is that multiple inheritance of interfaces is very useful, and that multiple inheritance of implementations is not missed, so may as well leave the latter out and avoid the complications.
 
As
 
class I
{
public:
virtual void f() = 0;
}
 
class A : public B, public virtual I
 
is directly analogous to inheriting from an interface, I don't see how a Java or C# guy could object.
 
Still, it seems public virtual inheritance is rarely used in C++ code, as compared to interfaces in Java and C#. Perhaps it is because C++ has const, which effectively gives a class two "interfaces", roughly speaking, a mutable and an immutable one. In Java and C#, these would be supported as interfaces.
 
Daniel
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 27 08:59PM

On 27/01/2016 20:51, Daniel wrote:
 
> class A : public B, public virtual I
 
> is directly analogous to inheriting from an interface, I don't see how a Java or C# guy could object.
 
> Still, it seems public virtual inheritance is rarely used in C++ code, as compared to interfaces in Java and C#. Perhaps it is because C++ has const, which effectively gives a class two "interfaces", roughly speaking, a mutable and an immutable one. In Java and C#, these would be supported as interfaces.
 
I think it is fine to use MI as long as only one derivation is public
with any others being private which means "implemented-in-terms-of"
relationship rather than "is-a" sausages.
 
/Flibble
scott@slp53.sl.home (Scott Lurndal): Jan 27 09:05PM

>fathom why.
 
>Am I missing something? Do we need to explore a premise further?
>What are your thoughts?
 
It's all a waste of time. Write programs that solve the stated
problem and don't worry about what someone else says is the right
or wrong way to do things.
 
There's nothing fundamentally wrong with multiple inheritance. Like
any language feature, it can be misused, but that shouldn't preclude
its use.
 
Note that an abstract class (pure virtual) is functionally indistinguishable from a
Java or C# interface.
"Öö Tiib" <ootiib@hot.ee>: Jan 27 01:13PM -0800

On Wednesday, 27 January 2016 22:16:36 UTC+2, Christopher Pisz wrote:
> fathom why.
 
> Am I missing something? Do we need to explore a premise further?
> What are your thoughts?
 
If a feature is simplifying writing working software then we should
use it.
 
Run-time dynamic polymorphism in general and multiple inheritance in
particular are complex features and so only sometimes simplify
writing software. KISS, DRY, YAGNI
 
There are number of other popular programming languages that have
multiple inheritance (for example Python, Common Lisp and Scala).
 
C# does not matter. When we program in some other language then it
is irrelevant what one can or can not do in C#.
Christopher Pisz <nospam@notanaddress.com>: Jan 27 03:14PM -0600

On 1/27/2016 2:40 PM, 4ndre4 wrote:
> real case, where C# interfaces prove to be a better solution than C++
> abstract classes, or vice versa. The only problem with mi that comes to
> my mind is the classic diamond problem.
 
I agree 100% the diamond problem is a problem, but I can just as easily
adapt the "An interface does not contain functionality or data" and then
the diamond problem is no longer a problem, right?
 
if my C++ "interface" is an abstract class (since we don't have a
interface keyword", which contains 100% pure virtuals, then I don't
think there is a problem, since D, in the examples, would be forced to
implement the the method. But it would be up to the developers to
enforce the rules that 'thou shalt only multiple inherit from abstract
classes with 100% pure virtual methods', which would be difficult, i
agree, to enforce. Doable none the less.
 
 
 
 
--
I have chosen to troll filter/ignore all subthreads containing the
words: "Rick C. Hodgins", "Flibble", and "Islam"
So, I won't be able to see or respond to any such messages
---
Cholo Lennon <chololennon@hotmail.com>: Jan 27 06:36PM -0300

On 01/27/2016 05:16 PM, Christopher Pisz wrote:
> fathom why.
 
> Am I missing something? Do we need to explore a premise further?
> What are your thoughts?
 
Well, in its last version (8), Java added default implementation for
interface methods (aka default methods). Why? IMO, it's because in a lot
of situations you need a default behavior (as simple as an empty code
for example), but with the mentioned restriction to multiple inheritance
of classes , that could not be done. C++ doesn't have that problem (but
C# still has it). Also, MI + abstract classes in C++ are more powerful
than interfaces with default methods in Java ;-)
 
 
Regards
 
 
--
Cholo Lennon
Bs.As.
ARG
Jerry Stuckle <jstucklex@attglobal.net>: Jan 27 04:40PM -0500

On 1/27/2016 3:16 PM, Christopher Pisz wrote:
> on the topic.
 
> He has put forth the following
 
> Premise: Multiple inheritance is universally accepted as bad
 
Premise: Any premise that says something is "universally accepted" is bad.
 
> Conclusion: Although the compiler allows you to, you should never use
> multiple inheritance in C++
 
Premise: Statements which use "never" are never correct (including this
one).
 
> because of the former premise.
> Conclusion: Inheriting from an interface in C# "doesn't count" as
> multiple inheritance and you _should_ do it
 
An interface in c# is nothing more than a an abstract class with no data
members in C++.
 
 
> Premise: I can create an interface in C++ the same as you can in C#
> Premise: I can inherit from interfaces in the same manner as you can in C#
> Conclusion: If you can do it I can too and, in fact, I should do it.
 
I agree completely.
 
> fathom why.
 
> Am I missing something? Do we need to explore a premise further?
> What are your thoughts?
 
I will, however, say I have see multiple inheritance misused more than
used correctly. It's not as bad when the base class has no data
members, effectively acting as a C# interface. Having only pure virtual
functions makes it even better.
 
But there are times when it can be useful, and I have occasionally used
it in the past. But not often.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Vir Campestris <vir.campestris@invalid.invalid>: Jan 27 09:43PM

On 27/01/2016 20:16, Christopher Pisz wrote:
> Premise: Multiple inheritance is universally accepted as bad
> Conclusion: Although the compiler allows you to, you should never use
> multiple inheritance in C++
 
I've used it exactly once.
 
There was a feature in the spec which described data of three types.
That's OK, except there were consumers which could take types a or b,
and those that could take b or c (and some that could take any of
them!). We found it easiest to make classes for a, b, and c, and to make
an ab class deriving from a and b, and a bc class deriving from b & c.
 
The spec BTW was an open standard. We always wondered what they smoked
in the comi9ttee meetings!
 
Andy
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 27 09:46PM

On 27/01/2016 21:05, Scott Lurndal wrote:
 
> Note that an abstract class (pure virtual) is functionally indistinguishable from a
> Java or C# interface.
 
In C++ "abstract base class" doesn't mean "interface" it means a class
with *at least* one pure virtual function.
 
There is nothing wrong with using the term "interface" when talking
about C++ code *if* one is referring to a class which:
 
* contains pure virtual functions with no implementation;
* contains trivial inline helper functions which call the pure virtual
functions;
* does not contain a class invariant.
 
I like to use the term "mixin" for the other type of abstract base class
which is basically used to implement the template method design pattern
sausages.
 
/Flibble
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 27 11:06PM +0100

On 1/27/2016 9:16 PM, Christopher Pisz wrote:
> Conclusion: Although the compiler allows you to, you should never use
> multiple inheritance in C++
 
I.e. don't use mixin classes.
 
That would be seriously dumb.
 
E.g.,
 
class Foo
: Non_copyable, // Common with Boost'ed code.
, Relops_from_compare< Foo > // Original case for BN trick.
, Small_objects_alloc< Foo > // Smth. like that from Loki.
{
public:
friend
auto compare( In_<Foo> A, In_<Foo> B )
-> int
{ ... }
};
 
 
Cheers & hth.,
 
- Alf
 
PS: Since I see no-one has so far mentioned it, to emulate Java/C#
inheritance in C++, so that an inherited class can provide an
implementation of an interface, one must use virtual inheritance.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 27 10:12PM

On 27/01/2016 22:06, Alf P. Steinbach wrote:
 
> PS: Since I see no-one has so far mentioned it, to emulate Java/C#
> inheritance in C++, so that an inherited class can provide an
> implementation of an interface, one must use virtual inheritance.
 
Why would you want to emulate Java/C# inheritance in C++? If you are
using C++ then use C++.
 
/Flibble
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jan 27 08:51PM

On Wed, 27 Jan 2016 10:00:52 -0500
 
> > How does it do that?
 
> When the automatic object of type std::vector<...> goes out of scope,
> the d-tor is called, and *in it* the dynamic memory (if any) is freed.
 
In case Bill is confused by this and thinks that this is no advantage
over static allocation, the rider should be added to the last statement
"if you have not moved ownership of the dynamic memory elsewhere".
 
You can move the memory held by a vector to another vector. If you do
that the original vector will safely destroy itself when it goes out of
scope but not interfere with the ownership of its successor.
 
Chris
Victor Bazarov <v.bazarov@comcast.invalid>: Jan 27 05:09PM -0500

On 1/27/2016 3:51 PM, Chris Vine wrote:
 
> In case Bill is confused by this and thinks that this is no advantage
> over static allocation, the rider should be added to the last statement
> "if you have not moved ownership of the dynamic memory elsewhere".
 
I am not sure the additional "rider" is needed given the "(if any)" is
already there. But if you feel it makes it /clearer/ to Bill, by all
means...
 
 
> You can move the memory held by a vector to another vector.
 
... which effectively takes the memory in the given vector and by the
time its d-tor executes, there is no dynamic memory *for it* to free.
The same result might be achieved by clearing the vector (the ownership
of said dynamic memory is optionally returned to the free store).
 
> that the original vector will safely destroy itself when it goes out of
> scope but not interfere with the ownership of its successor.
 
> Chris
 
V
--
I do not respond to top-posted replies, please don't ask
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 27 08:09PM

'int' considered dangerous: use a <cstdint> sized integer typedef instead.
 
On a related matter eschewing unsigned integer types is foolish as one
should use an unsigned type when dealing with unsigned values.
 
On another related matter the return type of std::uncaught_exceptions is
incorrect: it should probably be std::size_t.
 
/Flibble
 
P.S. Sausages.
Christopher Pisz <nospam@notanaddress.com>: Jan 27 02:17PM -0600

On 1/27/2016 2:09 PM, Mr Flibble wrote:
> incorrect: it should probably be std::size_t.
 
> /Flibble
 
> P.S. Sausages.
 
I guess your weekly, "Let's post the same fucking thing again and see if
people will argue about it yet again" alarm has gone off.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 27 08:27PM

On 27/01/2016 20:17, Christopher Pisz wrote:
 
>> P.S. Sausages.
 
> I guess your weekly, "Let's post the same fucking thing again and see if
> people will argue about it yet again" alarm has gone off.
 
I thought I was in your killfile mate? Judging by the quality of your
other posts in this NG recently it would probably benefit a lot of
people if you re-added me to it sausages.
 
/Flibble
Gareth Owen <gwowen@gmail.com>: Jan 27 09:39PM


> On a related matter eschewing unsigned integer types is foolish as one
> should use an unsigned type when dealing with unsigned values.
 
Two simple rules:
i) use an unsigned type when dealing with unsigned values
ii) there are (almost) no unsigned values
iii) sausages
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 27 09:50PM

On 27/01/2016 21:39, Gareth Owen wrote:
> i) use an unsigned type when dealing with unsigned values
> ii) there are (almost) no unsigned values
> iii) sausages
 
ii) and iii) are in conflict as you cannot eat a negative number of
sausages.
 
/Flibble
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 27 08:54PM

On Wed, 2016-01-27, David Brown wrote:
>> what Juha N. wanted to say, too.
 
> That makes more sense, at least regarding Python. But "auto" in C++ is
> still static typing - it is just not necessarily explicit typing.
 
Yes, and that's precisely what I was trying to convey above. I'm
familiar with the concepts: my first CS course, 26 years ago, used
Standard ML, where type inference works just like auto does in C++11.
 
(Just in case you were trying to educate me personally.)
 
...
> So "auto" is not really circumventing either the strong typing system,
> or the static typing system - it is merely reducing the verbosity of the
> code.
 
But it's not just about verbosity! Someone has to read -- and
understand -- the code, too ... more times than someone else has to
write it, hopefully.
 
Part of the reason I'm worried is the focus on the writers rather than
the readers.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
David Brown <david.brown@hesbynett.no>: Jan 27 10:15PM +0100

On 27/01/16 21:54, Jorgen Grahn wrote:
> familiar with the concepts: my first CS course, 26 years ago, used
> Standard ML, where type inference works just like auto does in C++11.
 
> (Just in case you were trying to educate me personally.)
 
No, I was just trying to get the details clear, especially on the
differences between C++ auto and Python typing. (I agree that C++ auto
and ML are similar or even identical - but I am not familiar enough with
ML languages to be precise.)
 
 
> But it's not just about verbosity! Someone has to read -- and
> understand -- the code, too ... more times than someone else has to
> write it, hopefully.
 
That is why reducing verbosity is a good thing (as long as it does not
reduce clarity). You don't have to write out the type explicitly if it
is not needed, nor do you have to read it if it does not add anything to
your understanding of the code.
 
 
> Part of the reason I'm worried is the focus on the writers rather than
> the readers.
 
That is my focus is not on writers when saying that auto is good at
reducing verbosity. But I fully agree with you that being able to
/read/ the code easily is more important than being able to write it easily.
"Öö Tiib" <ootiib@hot.ee>: Jan 27 11:59AM -0800

On Wednesday, 27 January 2016 03:13:15 UTC+2, Alf P. Steinbach wrote:
> efficient compile time evaluation when one knows the arguments allow
> that, or reasonably efficient checking for data known only at run time.
 
> Is there any way to /automate/ that choice?
 
Following example may be of use:
 
#include <iostream>
#include <type_traits>

template<typename T>
constexpr typename std::remove_reference<T>::type makeprval(T && t)
{
return t;
}
 
#define isprvalconstexpr(e) noexcept(makeprval(e))

int main(int argc, char *argv[])
{
int a = 1;
const int b = 2;
constexpr int c = 3;
const int d = argc;
 
std::cout << isprvalconstexpr(a) << std::endl ;
std::cout << isprvalconstexpr(b) << std::endl ;
std::cout << isprvalconstexpr(c) << std::endl ;
std::cout << isprvalconstexpr(d) << std::endl ;
}
 
It outputs:

0
1
1
0
 
That can be perhaps used to select the algorithm? I think I took it
from SO answer of Johannes Schaub and there was something about
limitations but don't remember what question it was.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 27 09:39PM +0100

On 1/27/2016 8:59 PM, Öö Tiib wrote:
 
> That can be perhaps used to select the algorithm? I think I took it
> from SO answer of Johannes Schaub and there was something about
> limitations but don't remember what question it was.
 
That's pure genius. :)
 
But then, his trick for accessing private members was also pure genius.
 
 
Cheers, & thanks,
 
- Alf
Daniel <danielaparker@gmail.com>: Jan 27 10:11AM -0800

On Wednesday, January 27, 2016 at 12:31:27 PM UTC-5, Alf P. Steinbach wrote:
 
> > They do :-)
 
> Uhm, not sure how you arrive at that conclusion, so not sure what to
> explain.
 
You're right.
 
I was asking about these constructors
 
vector(const vector&, const Allocator&);
vector(vector&&, const Allocator&);
 
I took your statement "there are no such constructors" to mean that such constructors did not exist, but I see you were just pointing out that they were not by definition copy or move constructors.
 
My question was whether these were required in order for a container to be "allocator aware", and as Öö Tiib replied, the answer is yes.
 
Thanks,
Daniel
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: