Topic: An entity in between namespaces and classes
Author: kprateek88@yahoo.com (Prateek R Karandikar)
Date: Wed, 19 May 2004 14:43:57 +0000 (UTC) Raw View
> > * It will be a scope.
> > * It will *not* be a type. Consequently, one cannot use it in compound
> > types, declare variables of it, etc.
> [snip]
>
> What advantage do you gain by preventing instantiation of it?
> Put another way, can you give an example where the fact that a
> typical traits class can be instantiated allowed an error to go
> undetected?
Why do we write
const std::string x=a;
instead of
std::string x=a;
when we know x won't change? Because const reflects our intentions
more accurately and helps the compiler in catching our inadvertent
errors( eg x=b;) Similary, suppose we write:
iterator_traits<T> *x= new iterator_traits<T>;
This would most likely be an error, and the compiler could have caught
it had iterator_traits been a nameclass.
Another example:
Suppose, for our library, we are writing some class/nameclass like
char_traits, which we don't expect anyone to instantiate ( I mean
instantiation of objects from classes, not template instantiation).
Suppose we forget to make a member function static. The compiler would
not catch the error when looking at the class definition, nor will it
catch the error at template-instantiation time. It will catch the
error only when someone tries to use the non-static member function
with ::. However, had our traits class been a nameclass, the error
would have been caught earlier ( While looking at the nameclass
definition).
In other words, having a non-static member function in a traits class
is ( most likely) only a logic error right now, but it would become a
language-enforced error with nameclasses.
---
[ 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: jdennett@acm.org (James Dennett)
Date: Wed, 19 May 2004 17:15:08 +0000 (UTC) Raw View
Prateek R Karandikar wrote:
>>>* It will be a scope.
>>>* It will *not* be a type. Consequently, one cannot use it in compound
>>>types, declare variables of it, etc.
>>
>>[snip]
>>
>>What advantage do you gain by preventing instantiation of it?
>> Put another way, can you give an example where the fact that a
>> typical traits class can be instantiated allowed an error to go
>> undetected?
>
>
>
> Why do we write
> const std::string x=a;
> instead of
> std::string x=a;
> when we know x won't change? Because const reflects our intentions
> more accurately and helps the compiler in catching our inadvertent
> errors( eg x=b;) Similary, suppose we write:
>
> iterator_traits<T> *x= new iterator_traits<T>;
The point is that errors in accidentally modifying a
variable (maybe by modifying the wrong variable) are
common, but accidentally creating an iterator_traits
object is possibly something that has never happened.
At the very least, it's vanishingly rare. That reduces
the value of such a change -- possibly to the point
where it's not worth the cost, unless there are other
reasons for it.
-- James
---
[ 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: kprateek88@yahoo.com (Prateek R Karandikar)
Date: Sun, 9 May 2004 03:28:50 +0000 (UTC) Raw View
Consided iterator_traits, numeric_limits, char_traits, unary_function,
iterator, etc. These do not really represent "data types", but just
bundle together declarations. Members are either types or are static.
So, conceptually they are closer to namespaces, and not
classes/structs. But they cannot be implemented in C++ as namespaces
as they have to be templated. So there should be an entity that is in
between a namespace and a class, which can be used to implement
iterator_traits, etc, and can be templated. Here I use the term
"nameclass" to mean this entity (although that is not a very suitable
name, but I cannot think of any meaningful name). Some possible
properties of a nameclass could be:
* It will be a scope.
* It will *not* be a type. Consequently, one cannot use it in compound
types, declare variables of it, etc.
* However, it can be "derived" from. This will be useful for deriving
from unary_function, iterator etc. I put "derived" in double quotes
here because this is not the OOP inheritace mechanism, but just a
shorthand to get the required declarations. In case a
class/struct/union derives from a nameclass, the non-type members of
the nameclass would become static members of the class/st/un.
* It can be templated.
* It can be passed as a template argument. Given this, we could write:
template <typename Ch>
nameclass std::char_traits {} ;
template <> nameclass std::char_traits<char> {/*...*/} ;
tempate < typename Ch, nameclass Tr = std::char_traits<Ch> >
class std::basic_ostream : virtual public std::basic_ios <Ch,Tr>
{/*...*/};
* Only the types of declarations allowed directly in namespaces will
be allowed in nameclasses. No constructors, virtual functions, etc,
because a nameclass isn't a type in the first place.
* There will be no access control. All members will be public.
* The rules for instantiation and specialization of nameclasses will
be analogous to the corresponding rules for classes.
* It will be closed, unlike a namespace.
* using-declarations and using-directives will not be applied to it.
* It will not be aliased.
* A nameless nameclass will not be allowed.
* A semicolon will be required after the declaration and the
definition of a nameclass.
Especially with templates, these nameclasses would be very convenient,
for traits/policies or as useful bases. Since nameclasses are
conceptually distinct from types, it would be better if there was a
way to represent them directly in the language. This will involve
adding a new keyword, but that can be avoided by cleverly overloading
an existing keyword ( or a combination thereof). Eg. "namespace class"
can be used to mean a nameclass.
Prateek Karandikar
---
[ 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: helmut.zeisel@aon.at (Helmut Zeisel)
Date: Mon, 10 May 2004 11:12:52 +0000 (UTC) Raw View
Prateek R Karandikar wrote:
> Consided iterator_traits, numeric_limits, char_traits, unary_function,
> iterator, etc. These do not really represent "data types", but just
> bundle together declarations. Members are either types or are static.
> So, conceptually they are closer to namespaces, and not
> classes/structs.
This depends on your concepts.
> But they cannot be implemented in C++ as namespaces
> as they have to be templated. So there should be an entity that is in
> between a namespace and a class,
Why? They work fine as class/struct; what problem would you solve that
cannot be solved otherwise? Maybe it is enough to change your "concept"
of a class/struct?
Helmut
---
[ 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: llewelly.at@xmission.dot.com (llewelly)
Date: Tue, 11 May 2004 06:05:28 +0000 (UTC) Raw View
kprateek88@yahoo.com (Prateek R Karandikar) writes:
> Consided iterator_traits, numeric_limits, char_traits, unary_function,
> iterator, etc. These do not really represent "data types", but just
> bundle together declarations. Members are either types or are static.
> So, conceptually they are closer to namespaces, and not
> classes/structs. But they cannot be implemented in C++ as namespaces
> as they have to be templated. So there should be an entity that is in
> between a namespace and a class, which can be used to implement
> iterator_traits, etc, and can be templated. Here I use the term
> "nameclass" to mean this entity (although that is not a very suitable
> name, but I cannot think of any meaningful name). Some possible
> properties of a nameclass could be:
>
> * It will be a scope.
> * It will *not* be a type. Consequently, one cannot use it in compound
> types, declare variables of it, etc.
[snip]
What advantage do you gain by preventing instantiation of it?
Put another way, can you give an example where the fact that a
typical traits class can be instantiated allowed an error to go
undetected?
---
[ 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: cdiggins@videotron.ca ("christopher diggins")
Date: Tue, 11 May 2004 17:57:22 +0000 (UTC) Raw View
===================================== MODERATOR'S COMMENT:
Please don't overquote.
===================================== END OF MODERATOR'S COMMENT
"Prateek R Karandikar" <kprateek88@yahoo.com> wrote in message
news:607f883e.0405080357.52234973@posting.google.com...
> Consided iterator_traits, numeric_limits, char_traits, unary_function,
> iterator, etc. These do not really represent "data types", but just
> bundle together declarations. Members are either types or are static.
> So, conceptually they are closer to namespaces, and not
> classes/structs. But they cannot be implemented in C++ as namespaces
> as they have to be templated. So there should be an entity that is in
> between a namespace and a class, which can be used to implement
> iterator_traits, etc, and can be templated. Here I use the term
> "nameclass" to mean this entity (although that is not a very suitable
> name, but I cannot think of any meaningful name). Some possible
> properties of a nameclass could be:
>
> * It will be a scope.
> * It will *not* be a type. Consequently, one cannot use it in compound
> types, declare variables of it, etc.
> * However, it can be "derived" from. This will be useful for deriving
> from unary_function, iterator etc. I put "derived" in double quotes
> here because this is not the OOP inheritace mechanism, but just a
> shorthand to get the required declarations. In case a
> class/struct/union derives from a nameclass, the non-type members of
> the nameclass would become static members of the class/st/un.
> * It can be templated.
> * It can be passed as a template argument. Given this, we could write:
>
> template <typename Ch>
> nameclass std::char_traits {} ;
>
> template <> nameclass std::char_traits<char> {/*...*/} ;
>
> tempate < typename Ch, nameclass Tr = std::char_traits<Ch> >
> class std::basic_ostream : virtual public std::basic_ios <Ch,Tr>
> {/*...*/};
>
> * Only the types of declarations allowed directly in namespaces will
> be allowed in nameclasses. No constructors, virtual functions, etc,
> because a nameclass isn't a type in the first place.
> * There will be no access control. All members will be public.
> * The rules for instantiation and specialization of nameclasses will
> be analogous to the corresponding rules for classes.
> * It will be closed, unlike a namespace.
> * using-declarations and using-directives will not be applied to it.
> * It will not be aliased.
> * A nameless nameclass will not be allowed.
> * A semicolon will be required after the declaration and the
> definition of a nameclass.
>
> Especially with templates, these nameclasses would be very convenient,
> for traits/policies or as useful bases. Since nameclasses are
> conceptually distinct from types, it would be better if there was a
> way to represent them directly in the language. This will involve
> adding a new keyword, but that can be avoided by cleverly overloading
> an existing keyword ( or a combination thereof). Eg. "namespace class"
> can be used to mean a nameclass.
>
> Prateek Karandikar
I think this is a very interesting idea, which I have also been considering
recently for my programming language Heron. I think you will definitely see
something akin to this eventually in C++. It is inevitable that as template
parameters and meta-programming become more and more complex, we will want
to bundle types into struct like groups and returns them from
meta-functions. An example of where something like this would be useful is
to replace macros. For instance the Visual C++ Windows library includes:
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows
headers
This seems to me something that would be more appropriately passed as a
parameter to a namespace. Any other ideas on applications of parameterized
namespaces with inheritance?
--
Christopher Diggins
http://www.cdiggins.com
http://www.heron-language.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 ]