Topic: Why are using directives not allowed at class scope?


Author: "Hans Salvisberg" <z1@salvisberg.com>
Date: Wed, 14 May 2003 12:22:45 CST
Raw View
Allan W wrote in message
<7f2735a5.0305081110.3f1802ec@posting.google.com>...
>Exactly what would this affect -- the class implementation?
>
>    class someclass {
>        using namespace std;
>        void somefunc();
>        // ...
>    };
>    int cout; // Presumably okay, because the directive doesn't
>              // affect the rest of the xlation unit... right?
>    void someclass:somefunc() {
>        cout << ::cout; // The first cout WOULD refer to std::cout,
>                        // because of the hypothetical class using
directive
>    }
>
>Is this what you meant?


I mean more than that. Class scope using directives would affect the class
scope, meaning the class definition as well as the class implementation.

For inline functions, all class scope names are known from the top of the
class definition. OTOH nested classes and typedefs aren't known until
they're defined. Whether class scope using directives should affect the
entire class definition or just from their position onwards is debatable. I
see arguments in favor of either way, but for practical purposes it wouldn't
really matter because good style would mandate putting using directives
at/near the top of the class definition anyway.

Yes, your example should work, because the using directive imports std::cout
into the class scope, thus hiding ::cout. However, I see the potential
benefit of allowing this mostly in the class definition, as Roger Orr has
nicely demonstrated in his reply to your post, and in member functions that
live in header files (inline member functions and template member
functions).

>You can achieve a similar effect (but not for inline functions) by
>moving all of the class function definitions into a separate
>compilation unit, and using a file-scope using directive there.
>Is there some reason why that isn't sufficient?

Using directives in the class definition would not completely replace using
directives at the top of the implementation file nor save you from
explicitely qualifying return types of out-of-line inline/template member
functions, because the return types of out-of-line member functions are not
in the class scope, but they would provide much more than a using directive
at the top of the implementation file does.

Also, I think class scope using directives would be cleaner than
file/namespace scope using directives, because they're in a "more local"
scope.

Hans



---
[ 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: "Hans Salvisberg" <z1@salvisberg.com>
Date: Wed, 14 May 2003 11:16:46 CST
Raw View
KIM Seungbeom wrote in message ...
>We could imagine the effect of class-scope using directives as
>the effect of repeating the using directives inside each member function:
>
>    void someclass::somefunc()
>    {
>        using namespace std;
>        cout << ::cout;
>    }


For this example -- yes. However, class scope includes the parameter list of
the member functions in addition to the function bodies. It does not include
the return types though.

Also, function scope and class scope of derived classes are nested inside
the class scope.

Hans



---
[ 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: musiphil@bawi.org (KIM Seungbeom)
Date: Fri, 9 May 2003 17:20:13 +0000 (UTC)
Raw View
allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0305081110.3f1802ec@posting.google.com>...
>
> Exactly what would this affect -- the class implementation?
>
>     class someclass {
>         using namespace std;
>         void somefunc();
>         // ...
>     };
>     int cout; // Presumably okay, because the directive doesn't
>               // affect the rest of the xlation unit... right?
>     void someclass:somefunc() {
>         cout << ::cout; // The first cout WOULD refer to std::cout,
>                         // because of the hypothetical class using directive
>     }
>
> Is this what you meant?

We could imagine the effect of class-scope using directives as
the effect of repeating the using directives inside each member function:

    void someclass::somefunc()
    {
        using namespace std;
        cout << ::cout;
    }

>
> You can achieve a similar effect (but not for inline functions) by
> moving all of the class function definitions into a separate
> compilation unit, and using a file-scope using directive there.
> Is there some reason why that isn't sufficient?

Class-scope using directives can simplify the class definition, too.

--
KIM Seungbeom <musiphil@bawi.org>

---
[ 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: Fri, 9 May 2003 22:42:20 +0000 (UTC)
Raw View
"Allan W" <allan_w@my-dejanews.com> wrote in message
news:7f2735a5.0305081110.3f1802ec@posting.google.com...

> You can achieve a similar effect (but not for inline functions) by
> moving all of the class function definitions into a separate
> compilation unit, and using a file-scope using directive there.
> Is there some reason why that isn't sufficient?

Well, templates spring to mind :-)
Also it is not just the implementation but also the class definition which
could benefit from being able to remove the namespace qualifiers.

For example [this is a genuine example with the names changed to protect the
guilty]:

class Test
{
public:
   void aMethod( someNS::nestedNS::class1 & input1, someNS::nestedNS::class2
& input2 );
   void anotherMethod( someNS::nestedNS::class1 & input1,
someNS::nestedNS::class2 & input2 );
   ...
};

versus:

class Test
{
   using namespace someNS::nestedNS;
public:
   void aMethod( class1 & input1, class2 & input2 );
   void anotherMethod( class1 & input1, class2 & input2 );
  ...
};

all you can do at present is:

class Test
{
   typedef someNS::nestedNS::class1 class1;
   typedef someNS::nestedNS::class2 class2;
public:
   void aMethod( someNS::nestedNS::class1 & input1, someNS::nestedNS::class2
& input2 );
   void anotherMethod( someNS::nestedNS::class1 & input1,
someNS::nestedNS::class2 & input2 );
   ...
};

which can get fairly painful when you have many names to alias.

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: allan_w@my-dejanews.com (Allan W)
Date: Thu, 8 May 2003 19:49:41 +0000 (UTC)
Raw View
"Hans Salvisberg" <z1@salvisberg.com> wrote
> Why can't we have using directives at class scope? I believe that 95% of all
> classes out there would immensely benefit from a succinct
>
>         using namespace std;
>
> at the top of the class definition, while still keeping things neat and
> tidy.

Exactly what would this affect -- the class implementation?

    class someclass {
        using namespace std;
        void somefunc();
        // ...
    };
    int cout; // Presumably okay, because the directive doesn't
              // affect the rest of the xlation unit... right?
    void someclass:somefunc() {
        cout << ::cout; // The first cout WOULD refer to std::cout,
                        // because of the hypothetical class using directive
    }

Is this what you meant?

You can achieve a similar effect (but not for inline functions) by
moving all of the class function definitions into a separate
compilation unit, and using a file-scope using directive there.
Is there some reason why that isn't sufficient?

---
[ 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: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Mon, 5 May 2003 15:23:40 +0000 (UTC)
Raw View

Hans Salvisberg schrieb:

> Most of the classes that I write use Standard Library features and I avoid
> using names from std for conflicting purposes. After a few years of
> faithfully writing qualified names in headers, the thrill has worn off
> pretty much, and the benefit of avoiding potential naming conflicts (which
> I've never actually experienced in 15 years of C++, except for with
> preprocessor macros...) is getting pale compared to the COBOL-like verbosity
> of "modern" C++.
>
> Why can't we have using directives at class scope? I believe that 95% of all
> classes out there would immensely benefit from a succinct
>
>         using namespace std;
>
> at the top of the class definition, while still keeping things neat and
> tidy.

Using directives at class scope are a good idea.

Also, it would be tremendously useful for this case (which requires additional
syntax for 'using'):

struct Memory_Manager
{
    // overloads operator new / delete and colleagues.
    // destructor NOT virtual
};


template <class AllocatorPolicy>
class MyClass : private AllocatorPolicy
{
using class AllocatorPolicy;
}


The reason behind this is follows:
AllocatorPolicy is basically an implementation detail. It is a leightweight
class supposed to work only as implementation detail, so it's destructor is not
virtual. That in turn saves some bytes, the small advantage.
In order to work correctly, part of Memory_Manager's interface has to make it's
way into the interface of a derived classs. We could use public inheritance, but
that would introduces another problems:

conversions from derived-class to base-class can occurr. This in turn would
allow treating the class polymorphic, but class MemoryManager is NOT intended as
a polymorphic base class; it is a simple implementation detail that happens to
find its way into the interface of derived classes. And using private
inheritance makes this clear. That's the big advantage.
Implementation details is what it is, implementation detail . Also
MemoryManager's destructor can be safely non-virtual, because derived-to-base
conversions don't apply anymore.
And the new syntax with "using class .." would be necessary in order to support
templates. Currently, using directives have to be written explicitly for every
member - a luxury usually not available when dealing with generic code.


best regards,

Thomas

---
[ 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: "Hans Salvisberg" <z1@salvisberg.com>
Date: 3 May 2003 19:55:42 GMT
Raw View
Most of the classes that I write use Standard Library features and I avoid
using names from std for conflicting purposes. After a few years of
faithfully writing qualified names in headers, the thrill has worn off
pretty much, and the benefit of avoiding potential naming conflicts (which
I've never actually experienced in 15 years of C++, except for with
preprocessor macros...) is getting pale compared to the COBOL-like verbosity
of "modern" C++.

Why can't we have using directives at class scope? I believe that 95% of all
classes out there would immensely benefit from a succinct

        using namespace std;

at the top of the class definition, while still keeping things neat and
tidy.

Hans

P.S. I know that using *declarations* are used at class scope (for a
slightly different purpose), but I'm talking about using *directives* here,
which are disallowed at class scope in C++ 98.


---
[ 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                       ]