Topic: Should class-member using declarations behave differently from namespace using declarations?


Author: philippe_mori@hotmail.com ("Philippe Mori")
Date: Thu, 14 Aug 2003 05:17:05 +0000 (UTC)
Raw View
> >Are you of the opinion that using declarations should never
> >be used to increase the accesibility of a name then?  Whilst
> >I admit that
> >
> >  class B {
> >    protected: void x();
> >  };
> >  class D : public B {
> >    public: using B::x;
> >  };
> >
> >is often symptomatic of bad design, I'm not at all
> >convinced that
> >
> >  class B {
> >    public: void x();
> >  };
> >  class D : private B {
> >    public: using B::x;
> >  };
> >
> >is a problem.  Both of these use a class scope using
> >declaration to increase accessibility.  I would be happy to
> >see the former made illegal (though I appreciate that it
> >would break too much existing code for this to be possible);
> >I am not happy about the latter being illegal.
>
> I am entirely in favour of that second use. I have always believed (but
> lacked the skill and authority to express it in the mid-90s) that class
> scope using declarations should reinstate the base class access whether
> the problem was hiding or access change because of the method of
> derivation.
>
> However I think it is water under the bridge and we will have to find
> another (less intuitive) way to provide the 'right' semantics.
>
>

IMO an usign directive should essentially "unhide" (up to the level where
it appears and the one it was declared - the most restrictive one) any
declaration that are not considered anymore because we either not
derive publicly or because some name were hidden.

IMO, rules should still be changed. Code that would be broken is
already broken (as it was the case for fixing for loop scope).

So in other words, if we derives with a lower access than the access
were the using declaration appears (we derives private and the using
in protected or public section or we derive protected and the using is
in public section), then for the declaration affected by the using,
lookup should be equivalent as if were deriving with a greater access.

Also, using would means than no inherited name would be hidden by
a declaration in the derived class. So if a declaration is not considered
because it is hidden (or if an error occurs for that same reason), it
should be ignored.

Using declaration would never make something visible if it were
not visible if public derivation was used and no name hidding occurs.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Thu, 24 Jul 2003 02:10:51 +0000 (UTC)
Raw View
In article <Pine.LNX.4.55.0307231055510.14460@sphinx.mythic-beasts.com>,
Richard Smith <richard@ex-parrot.com> writes
>Are you of the opinion that using declarations should never
>be used to increase the accesibility of a name then?  Whilst
>I admit that
>
>  class B {
>    protected: void x();
>  };
>  class D : public B {
>    public: using B::x;
>  };
>
>is often symptomatic of bad design, I'm not at all
>convinced that
>
>  class B {
>    public: void x();
>  };
>  class D : private B {
>    public: using B::x;
>  };
>
>is a problem.  Both of these use a class scope using
>declaration to increase accessibility.  I would be happy to
>see the former made illegal (though I appreciate that it
>would break too much existing code for this to be possible);
>I am not happy about the latter being illegal.

I am entirely in favour of that second use. I have always believed (but
lacked the skill and authority to express it in the mid-90s) that class
scope using declarations should reinstate the base class access whether
the problem was hiding or access change because of the method of
derivation.

However I think it is water under the bridge and we will have to find
another (less intuitive) way to provide the 'right' semantics.


--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Mon, 21 Jul 2003 18:33:49 +0000 (UTC)
Raw View
In article <4fb4137d.0307202059.2be243d5@posting.google.com>, johnchx
<johnchx2@yahoo.com> writes
>So, in at least one instance, this isn't undoing a design decision,
>but simply following the design.


However the blunt way class scope using declarations work is unfortunate
to say the least. I have no problem with the ability of a derived class
to make a protected function public but I have a big problem with being
able to republish interfaces when I need to. Note that using
declarations should allow 'unhiding' of names and the designer of the
derived class does not need to know the extent to which the name is
overloaded, his class will track the base class design. This is not
currently the case, and I suspect we will now have to invent an
alternative syntax to overcome what we have done.



--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Tue, 22 Jul 2003 02:01:00 +0000 (UTC)
Raw View
In article <Pine.LNX.4.55.0307211505560.8099@sphinx.mythic-beasts.com>,
Richard Smith <richard@ex-parrot.com> writes
>Francis Glassborow wrote:
>
>> No you are perfectly right however I am not convinced that it should be.
>
>But it breaks encapsulation by allowing members of one class
>access to the private members of another.
>
>  class B {
>    private: int x;
>  };
>
>  class D : public B {
>    void f() { cout << x << endl; }
>  };
>
>This is an error:  x is a private member of B so can't be
>accessed by D.  Now consider add a using declaration to D:
>
>  class D : public B {
>    private: using B::x;
>    void f() { cout << x << endl; }
>  };
>
>Now the name x is a private member of D, which can be
>accessed within D.
>
>By allowing this you allow derived classes to access *any*
>data member of a base class.  I think this would be a very
>bad idea indeed.

However we could have provided an alternative form in which the using
declaration still made the private member of the base class visible but
kept it unusable by D. What we have currently is that any name that is
overloaded with at least one private declaration cannot be handled via a
using declaration.

There is also the issue as to whether we should have had class scope
using declarations apply to data (they serve no useful purpose because
IIRC a name used for data cannot also be overloaded as a name for a
function.

I think that we did not think carefully enough about the issues when we
introduced class scope using declarations.


--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Wed, 23 Jul 2003 01:32:15 +0000 (UTC)
Raw View
In article <Pine.LNX.4.55.0307221422460.26164@sphinx.mythic-beasts.com>,
Richard Smith <richard@ex-parrot.com> writes
>Francis Glassborow wrote:
>
>> However we could have provided an alternative form in which the using
>> declaration still made the private member of the base class visible but
>> kept it unusable by D.
>
>I'm not sure I fully understand what you mean by "visible
>but ... unusable by D".  In the following code, do you want
>the using declaration to inject two aliases into D, one for
>each overload in B, with one having public accesibility and
>one having no accesibility?
>
>  class B {
>    private: void x(int);
>    public:  void x();
>  };
>
>  class D : public B {
>    public: using B::x;
>  };
>
>Imagine for a moment that there is an additional access-
>specifier, "inaccessible", meaning inaccessible even from
>within the class.  This would make the above definition of D
>equivalent to
>
>  class D : public B {
>    inaccessible: void x(int); // unimplemented
>    public:       void x() { return B::x(); }
>  };

Yes, exactly and overload resolution then precedes correctly and if
x(int) is selected a diagnostic is issued, exactly as would happen if
you had not declared any functions named x in the derived class. Note
that currently, if I need to override any function named x then I am in
trouble in the derived class because the overrider will hide the others
and the best I can do is to provide a private x(int) and not define it.
What makes it worse is that the private member functions stop being
implementation details, I have to know about them and any future
additions or removals of private members of the overload set.

>
>So what if the user wants to add another overload of x to
>the derived class:
>
>  class D : public B {
>   public:
>    using B::x;
>    void x(int);
>  };
>
>This would then be an redefinition of x(int), and so the
>presence (if not semnatics) of B::x(int) suddenly become
>part of the exposed interface of B.  (They have to be
>documented so users can avoid this type of problem.)

Check how overriders currently work in the presence of a using
declaration. I think you will find that they are fine.

>
>I'm not sure that allowing this extention is really
>particularlly useful.  It seems to me to just be moving the
>problem.

Unfortunately we cannot really allow this extension because the damage
is already done with the changed access rules for public and protected
members of an overload set.

>
>>  What we have currently is that any name that is
>> overloaded with at least one private declaration cannot be handled via a
>> using declaration.
>
>How common do you think this is?  I can't say I've ever been
>tempted to do this.  Isn't it better to just say "don't do
>it".

It means that we just about cannot inject ctors into a derived class by
extending the using declaration rules and that is something many people
definitely do want to do.

>
>> There is also the issue as to whether we should have had class scope
>> using declarations apply to data (they serve no useful purpose because
>> IIRC a name used for data cannot also be overloaded as a name for a
>> function.
>
>They can be used to break the accessibility specified in the
>base class, e.g.
>
>  class B {
>    protected: int x;
>  };
>
>  class D : public B {
>    public: using B::x;
>  };
>
>Not a particularly good thing to be encouraging, but a use
>none the less.

Now you are supporting poor coding as a justification. Note that under
what I wanted this breach of accessibility would not have been possible.

< snip>

--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rmaddox@isicns.com (Randy Maddox)
Date: Fri, 18 Jul 2003 15:12:05 +0000 (UTC)
Raw View
johnchx2@yahoo.com (johnchx) wrote in message news:<4fb4137d.0307172133.195ab48@posting.google.com>...
> rmaddox@isicns.com (Randy Maddox) wrote
>
> > > >And your comment here clearly shows that you are trying to make a
> > > >protected name be public.  That you cannot do.
> > >
> > > Of course you can, though I hate the way using declarations at class
> > > scope work the fact is that the declarations are injected with the
> > > access of the using declaration (and if any uses of the name are private
> > > and the using declaration is other than private we have an error but
> > > that is the only case.
>
> [snip]
>
> > I was so shocked by this response that I went back and checked the
> > Standard and you are absolutely correct, Francis.
>
> [snip]
>
> > IMHO this rather seems to violate
> > the whole concept of protected, but I do indeed stand corrected.
>
> Actually, I'd say that it clarifies -- rather than violates -- the
> concept of protected.  A derived class is permitted to do anything it
> wants with a protected member of a base class, including publishing it
> to all the world.
>

Well, that is certainly one way, and clearly the correct way, to look
at it, but what if I changed your statement just a bit to:

A friend class is permitted to do anything it wants with a private
member of its friend, including publishing it to all the world.

Similar conceptually, but does this make sense?  I hear what you're
saying with respect to protected, but it still bothers me that it
works that way.  The designer of the base class chose protected access
for some reason, and at least part of that reason was that they didn't
feel public access was correct.  This behavior allows that decision to
be undone in a derived class, and that's what bothers me.  Undoing a
base class design decision in a derived class just doesn't feel right
to me.  Clearly this is no different than if the derived class
provided a public forwarding member that called the base class
protected member, but that at least seems more explicit and is clearly
documented by the code itself.

Randy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: richard@ex-parrot.com ("Richard Smith")
Date: Fri, 18 Jul 2003 20:29:00 +0000 (UTC)
Raw View
Francis Glassborow wrote:

> Of course you can, though I hate the way using declarations at class
> scope work the fact is that the declarations are injected with the
> access of the using declaration (and if any uses of the name are private
> and the using declaration is other than private we have an error but
> that is the only case.

Apologies if I'm misunderstanding you, but are you saying that the following
is *not* an error?

  class B {
    private: int x;
  };

  class D : public B {
    private: using B::x;
  };

By my reading of 7.3.3/14,

| All instances of the name mentioned in a using-declaration shall
| be accessible.  In particular, if a derived class uses a using-
| declaration to access a member of a base class, the member name
| shall be accessible.

... B::x must be accessible, which it clearly is not in this case.

--
Richard Smith


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Fri, 18 Jul 2003 21:18:09 +0000 (UTC)
Raw View
In article <8c8b368d.0307170455.4d0938f2@posting.google.com>, Randy
Maddox <rmaddox@isicns.com> writes
>francis@robinton.demon.co.uk (Francis Glassborow) wrote in message
>news:<NtkmfXBkQZF$Ew+v@robinton.demon.co.uk>...
>>
>
>I was so shocked by this response that I went back and checked the
>Standard and you are absolutely correct, Francis.  Although it seems
>extremely counter-intutitive that a using declaration could make a
>protected name public, that exact example is provided in 7.3.3/15.  As
>you note, the only restriction apparently is that we cannot make a
>private name anything but private.  IMHO this rather seems to violate
>the whole concept of protected, but I do indeed stand corrected.
>
>
The argument is that it has always possible to make a protected function
public in a derived class. Where I object is that using declarations do
not allow me to be selective. In addition the rule has blocked what I
consider to be potentially more useful techniques. For example the
problem of reusing ctors from a base class in a derived class that adds
no data (or one where the programmer is happy that the extra data be
default initialised) cannot be dealt with by extending using
declarations because we often want to have explicitly private or
protected copy ctors that should not have their access level changed.

I believe that the access provided using declarations at class scope
should have been similar to the way access specifiers are applied to
base classes.

Now we have to explore alternative mechanisms because changing the rules
for using declarations would break too much legacy code.

It would have been helpful in some cases to be able to write:

class X : private Y {
public:
        using class Y;
// modifications etc.
};

In order to inject Y's interface into X without having the problems of
implicit conversion from X to Y. Now we have to consider alternative
syntax to achieve that objective.

--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Fri, 18 Jul 2003 22:34:19 +0000 (UTC)
Raw View
In article <bf62sn$kel$1$830fa79d@news.demon.co.uk>, Richard Smith
<richard@ex-parrot.com> writes
>
>Francis Glassborow wrote:
>
>> Of course you can, though I hate the way using declarations at class
>> scope work the fact is that the declarations are injected with the
>> access of the using declaration (and if any uses of the name are private
>> and the using declaration is other than private we have an error but
>> that is the only case.
>
>Apologies if I'm misunderstanding you, but are you saying that the following
>is *not* an error?
>
>  class B {
>    private: int x;
>  };
>
>  class D : public B {
>    private: using B::x;
>  };
>
>By my reading of 7.3.3/14,

No you are perfectly right however I am not convinced that it should be.

--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rogero@howzatt.demon.co.uk ("Roger Orr")
Date: Sat, 19 Jul 2003 01:37:02 +0000 (UTC)
Raw View
"Randy Maddox" <rmaddox@isicns.com> wrote in message
news:8c8b368d.0307180602.4584ee30@posting.google.com...
[snip]
> Similar conceptually, but does this make sense?  I hear what you're
> saying with respect to protected, but it still bothers me that it
> works that way.  The designer of the base class chose protected access
> for some reason, and at least part of that reason was that they didn't
> feel public access was correct.  This behavior allows that decision to
> be undone in a derived class, and that's what bothers me.  Undoing a
> base class design decision in a derived class just doesn't feel right
> to me.  Clearly this is no different than if the derived class
> provided a public forwarding member that called the base class
> protected member, but that at least seems more explicit and is clearly
> documented by the code itself.

I have no particular problem in principle with allowing a protected base
member being made public in a derived class.
<ASIDE>
At the risk of starting a flame war, which is not my intention, I think
protected is often abused by coders who can't decide whether the method
should be public or private.
</ASIDE>
The part that I don't like is that a using declaration applies the _same_
access to _all_ the methods with the given name, and so makes it possible to
inadvertently give access to a protected member with the same name as a
public member.
A contrived example:

class Base
{
protected:
   void aMethod( int someValue );
public:
   void aMethod();
};

class Derived : Base
{
public:
   using Base::aMethod;
};

However I don't consider this is likely to be cause a real problem in most
code.

Roger Orr
--
MVP in C++ at www.brainbench.com


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: philippe_mori@hotmail.com ("Philippe Mori")
Date: Sun, 20 Jul 2003 00:51:44 +0000 (UTC)
Raw View
>
> class Base {
>    protected:
>      template <typename T>
>      void f(const T &) { }
>
>      void f(const int &) { }
> };
>
> class Derived : public Base {
>    public:
>      using Base::f; // make inherited f public
> };
>
> Both compilers complain that Base::f(const T&) with T = double is
> protected (Comeau says 'error: function "Base::f(const T &) [with
> T=double]" is inaccessible' and g++ says "`void Base::f(const T&) [with
> T = double]' is protected within this context").
>

I was always thinking that it was working that way... That is that we
cannot give more access to a member in a derived class by an using
declaration.

I think that the only way to give more access is when we derive
privatly (or protectedly), from a class... In that case, we could restore
the access to the original level.

class B1 {
public :
    void f();
};

class D1 : private B1 {
public:
    using B1::f;    // Restore f access to public...
};

IMHO, if there are many overload, each overload should have the
mimimum access between the original access and the access where
the using clause appears.

I think that your compilers are right... If I remember well, Borland
was also doing it that way.

Philipe

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Sun, 20 Jul 2003 10:44:11 +0000 (UTC)
Raw View
In article <KPkSa.7518$eP6.1076600@news20.bellglobal.com>, Philippe Mori
<philippe_mori@hotmail.com> writes
>I was always thinking that it was working that way... That is that we
>cannot give more access to a member in a derived class by an using
>declaration.
>
>I think that the only way to give more access is when we derive
>privatly (or protectedly), from a class... In that case, we could restore
>the access to the original level.
>
>class B1 {
>public :
>    void f();
>};
>
>class D1 : private B1 {
>public:
>    using B1::f;    // Restore f access to public...
>};
>
>IMHO, if there are many overload, each overload should have the
>mimimum access between the original access and the access where
>the using clause appears.
>
>I think that your compilers are right... If I remember well, Borland
>was also doing it that way.

Actually what I would have liked is a mechanism by which a private base
class can have all its three interfaces republished by a using
declaration. IOWs I would like to have been able to say 'I want a type
exactly like that one, but without any implicit conversions either for
objects or for pointers to objects.'

--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: johnchx2@yahoo.com (johnchx)
Date: Mon, 21 Jul 2003 15:06:02 +0000 (UTC)
Raw View
rmaddox@isicns.com (Randy Maddox) wrote
> johnchx2@yahoo.com (johnchx) wrote
> > Actually, I'd say that it clarifies -- rather than violates -- the
> > concept of protected.  A derived class is permitted to do anything it
> > wants with a protected member of a base class, including publishing it
> > to all the world.
> >
>
> Well, that is certainly one way, and clearly the correct way, to look
> at it, but what if I changed your statement just a bit to:
>
> A friend class is permitted to do anything it wants with a private
> member of its friend, including publishing it to all the world.
>
> Similar conceptually, but does this make sense?

Sensible or not, it is perfectly true.  All the more reason to be
careful choosing your friends.  :-)

There is also an important difference between granting friendship and
making a member protected: you know who your friends are.  You declare
a function or class a friend because you know it needs to be, and
because you trust it *completely* with the validity of your class
(often, though not always, because the class author also writes and
maintains the friend).

Making a member protected makes it accessible to every function and
class that wants to mess with it.  They just need to take the extra
step of introducing a derived class.


> I hear what you're
> saying with respect to protected, but it still bothers me that it
> works that way.  The designer of the base class chose protected access
> for some reason, and at least part of that reason was that they didn't
> feel public access was correct.


There's the rub: if public access isn't *safe* (i.e. making the member
public would allow clients to put the class into an invalid state, or
otherwise violate a class invariant), then protected access isn't
appropriate either, because (a) writers of derived classes are just as
likely to mess things up as any other user of the class and (b)
derived classes can grant access to all the world.

If public access *is* safe, then why not just grant it?

My general impression is that -- for "modern-style" OO designs (i.e.
where containment is prefered to inheritance for re-using
implementations) -- the protected access specifier is not very useful.
 (Most "modern" uses seem to fall into the category of "handy tricks,"
like making ctors and dtors protected.)


> This behavior allows that decision to
> be undone in a derived class, and that's what bothers me.  Undoing a
> base class design decision in a derived class just doesn't feel right
> to me.

Agreed...adding only that if I'm designing a class, I should look for
ways to ensure that my design decisions *can't* be undone  -- which
means that I shouldn't rely on protected access to keep members out of
the public interface.



Strangely enough, the one class library that I've worked with that
makes extensive use of protected members (Borland's VCL) is intended
to be used exactly this way.  The library provides a number of classes
intended to be used as base classes, and these provide few public
functions and lots of protected ones.  The user of the library derives
a new class from one of these bases, making as much, or a little, of
the protected interface public as she likes.  (The VCL is very much in
the "old" OO tradition of inheriting from implementation-heavy base
classes... in deep, deep hierarchies.)

So, in at least one instance, this isn't undoing a design decision,
but simply following the design.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pallas@cs.stanford.edu (Joe Pallas)
Date: Wed, 16 Jul 2003 02:05:28 +0000 (UTC)
Raw View
I cannot find anything in the standard that would account for this
peculiar difference in how using declarations behave when the name
being imported is an overload of both template and non-template
functions.  I am getting the same result from both g++ and (the online
test version of) Comeau.

When I have an template function with non-template overload in a
namespace, the using declaration imports both the template and
non-template versions, so that the code below compiles successfully.

namespace NS {
     template <typename T>
     void f(const T &) { }

     void f(const int &) { }
}

using NS::f;

int main() {
     f(7); // use specific version
     f(7.0); // use template version
     return 0;
}

Now I try to do what seems to be the same thing, only with class
members declarations, and both g++ and Comeau complain:

class Base {
   protected:
     template <typename T>
     void f(const T &) { }

     void f(const int &) { }
};

class Derived : public Base {
   public:
     using Base::f; // make inherited f public
};

int main() {
     Derived d;
     d.f(7); // use specific version
     d.f(7.0); // use template version
     return 0;
}

Both compilers complain that Base::f(const T&) with T = double is
protected (Comeau says 'error: function "Base::f(const T &) [with
T=double]" is inaccessible' and g++ says "`void Base::f(const T&) [with
T = double]' is protected within this context").

I can't find anything in section 7.3.3 (or 11.3) that would explain why
the namespace using-declaration imports both the template and
non-template functions, but the class-member using-declaration does
not.  In particular, I don't see anyway that the every-popular 7.3.3p5
statement "A using-declaration shall not name a template-id" could
explain this difference.

Are both compilers wrong (seems unlikely), or am I not reading the
standard correctly?  If the latter, what is the text that explains the
difference?

Thanks.
joe

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rmaddox@isicns.com (Randy Maddox)
Date: Wed, 16 Jul 2003 16:47:26 +0000 (UTC)
Raw View
pallas@cs.stanford.edu (Joe Pallas) wrote in message news:<EDA5B2A0-B6FF-11D7-9A62-000A959DF3B0@cs.stanford.edu>...
> I cannot find anything in the standard that would account for this
> peculiar difference in how using declarations behave when the name
> being imported is an overload of both template and non-template
> functions.  I am getting the same result from both g++ and (the online
> test version of) Comeau.
>
> When I have an template function with non-template overload in a
> namespace, the using declaration imports both the template and
> non-template versions, so that the code below compiles successfully.
>
> namespace NS {
>      template <typename T>
>      void f(const T &) { }
>
>      void f(const int &) { }
> }
>
> using NS::f;
>
> int main() {
>      f(7); // use specific version
>      f(7.0); // use template version
>      return 0;
> }
>
> Now I try to do what seems to be the same thing, only with class
> members declarations, and both g++ and Comeau complain:
>
> class Base {
>    protected:

Here's your problem.  These names are protected.

>      template <typename T>
>      void f(const T &) { }
>
>      void f(const int &) { }
> };
>
> class Derived : public Base {
>    public:
>      using Base::f; // make inherited f public

And your comment here clearly shows that you are trying to make a
protected name be public.  That you cannot do.

> };
>
> int main() {
>      Derived d;
>      d.f(7); // use specific version
>      d.f(7.0); // use template version
>      return 0;
> }
>
> Both compilers complain that Base::f(const T&) with T = double is
> protected (Comeau says 'error: function "Base::f(const T &) [with
> T=double]" is inaccessible' and g++ says "`void Base::f(const T&) [with
> T = double]' is protected within this context").

And the error messages are perfectly clear that the access specifier
is the problem.

>
> I can't find anything in section 7.3.3 (or 11.3) that would explain why
> the namespace using-declaration imports both the template and
> non-template functions, but the class-member using-declaration does
> not.  In particular, I don't see anyway that the every-popular 7.3.3p5
> statement "A using-declaration shall not name a template-id" could
> explain this difference.
>
> Are both compilers wrong (seems unlikely), or am I not reading the
> standard correctly?  If the latter, what is the text that explains the
> difference?
>
> Thanks.
> joe
>

I believe that if you just change protected to public in Base your
problem will go away.

Randy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kristov@arcor.de ("Christoph Schulz")
Date: Wed, 16 Jul 2003 17:06:54 +0000 (UTC)
Raw View
Randy Maddox <rmaddox@isicns.com> schrieb:

> pallas@cs.stanford.edu (Joe Pallas) wrote in message
> news:<EDA5B2A0-B6FF-11D7-9A62-000A959DF3B0@cs.stanford.edu>...
>>
>> class Base {
>>    protected:
>
> Here's your problem.  These names are protected.
>
>>      template <typename T>
>>      void f(const T &) { }
>>
>>      void f(const int &) { }
>> };
>>
>> class Derived : public Base {
>>    public:
>>      using Base::f; // make inherited f public
>
> And your comment here clearly shows that you are trying to make a
> protected name be public.  That you cannot do.
>

This is incorrect IMHO. 7.3.3/15 allows this:

  class A {
  //[...]
  protected:
    void g();
  };

  class B : public A {
  //[...]
  public:
    using A::g; // B::g is a public synonym for A::g
  };


Regards,
  Christoph


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Wed, 16 Jul 2003 21:28:57 +0000 (UTC)
Raw View
In article <8c8b368d.0307160458.7889773@posting.google.com>, Randy
Maddox <rmaddox@isicns.com> writes
>And your comment here clearly shows that you are trying to make a
>protected name be public.  That you cannot do.

Of course you can, though I hate the way using declarations at class
scope work the fact is that the declarations are injected with the
access of the using declaration (and if any uses of the name are private
and the using declaration is other than private we have an error but
that is the only case.


--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: google@vandevoorde.com (Daveed Vandevoorde)
Date: Thu, 17 Jul 2003 02:02:25 +0000 (UTC)
Raw View
pallas@cs.stanford.edu (Joe Pallas) wrote:
> I cannot find anything in the standard that would account for this
> peculiar difference in how using declarations behave when the name
> being imported is an overload of both template and non-template
> functions.  I am getting the same result from both g++ and (the online
> test version of) Comeau.

Strange, but I do think it's a bug in both compilers.

        Daveed

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: sebmol@yahoo.com ("Sebastian Moleski")
Date: Thu, 17 Jul 2003 02:59:07 +0000 (UTC)
Raw View
"Francis Glassborow" <francis@robinton.demon.co.uk> wrote in message
news:NtkmfXBkQZF$Ew+v@robinton.demon.co.uk...
> In article <8c8b368d.0307160458.7889773@posting.google.com>, Randy
> Maddox <rmaddox@isicns.com> writes
> >And your comment here clearly shows that you are trying to make a
> >protected name be public.  That you cannot do.
>
> Of course you can, though I hate the way using declarations at class
> scope work the fact is that the declarations are injected with the
> access of the using declaration (and if any uses of the name are private
> and the using declaration is other than private we have an error but
> that is the only case.

I'm trying to parse your sentences (which are lacking any interpunctation except
for the one opening parenthesis). Are you saying that using declarations should
not change the access level of the names they inject?

sm


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rmaddox@isicns.com (Randy Maddox)
Date: Fri, 18 Jul 2003 02:37:58 +0000 (UTC)
Raw View
francis@robinton.demon.co.uk (Francis Glassborow) wrote in message news:<NtkmfXBkQZF$Ew+v@robinton.demon.co.uk>...
> In article <8c8b368d.0307160458.7889773@posting.google.com>, Randy
> Maddox <rmaddox@isicns.com> writes
> >And your comment here clearly shows that you are trying to make a
> >protected name be public.  That you cannot do.
>
> Of course you can, though I hate the way using declarations at class
> scope work the fact is that the declarations are injected with the
> access of the using declaration (and if any uses of the name are private
> and the using declaration is other than private we have an error but
> that is the only case.
>
>
> --
> Francis Glassborow      ACCU
> 64 Southfield Rd
> Oxford OX4 1PA          +44(0)1865 246490
> All opinions are mine and do not represent those of any organisation
>

I was so shocked by this response that I went back and checked the
Standard and you are absolutely correct, Francis.  Although it seems
extremely counter-intutitive that a using declaration could make a
protected name public, that exact example is provided in 7.3.3/15.  As
you note, the only restriction apparently is that we cannot make a
private name anything but private.  IMHO this rather seems to violate
the whole concept of protected, but I do indeed stand corrected.

Randy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: johnchx2@yahoo.com (johnchx)
Date: Fri, 18 Jul 2003 06:11:00 +0000 (UTC)
Raw View
rmaddox@isicns.com (Randy Maddox) wrote

> > >And your comment here clearly shows that you are trying to make a
> > >protected name be public.  That you cannot do.
> >
> > Of course you can, though I hate the way using declarations at class
> > scope work the fact is that the declarations are injected with the
> > access of the using declaration (and if any uses of the name are private
> > and the using declaration is other than private we have an error but
> > that is the only case.

[snip]

> I was so shocked by this response that I went back and checked the
> Standard and you are absolutely correct, Francis.

[snip]

> IMHO this rather seems to violate
> the whole concept of protected, but I do indeed stand corrected.

Actually, I'd say that it clarifies -- rather than violates -- the
concept of protected.  A derived class is permitted to do anything it
wants with a protected member of a base class, including publishing it
to all the world.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]