C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Use of "traits" templates with namespaces

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
John M. Dlugosz
Guest





PostPosted: Mon Oct 11, 2004 11:28 am    Post subject: Use of "traits" templates with namespaces Reply with quote



I'm a C++ expert, but have always neglected the area of templates
because of horrible compiler support. But now that VC7.1 on the PC
(what I use at work) has something standard complient, and in light of
the body of metaprogramming and other patterns now open to me, I'm
studying up on the matter and doing some small projects at home to
gain some experience.

I've looked at "The Complete Guide" by Vandervoorde and Josuttis, and
at "Modern C++ Design" by Alexandrescu, and at the traits in the
standard library.

But everything I've read ignores the following issue:

Suppose my library is in namespace N1. That is, all my headers with
all my global stuff, including templates, are surrounded by namespace
N1 { ... }. In my library I have a traits template, say Traits<T>.
That's actually N1::Traits<T>.

The user then creates a program, or another library, and puts all of
his stuff in namespace N2. He creates a class C that he wants to use
with my library, so he needs to define an explicit specialization for
N1::Traits<C>.

However, his source file is surrounded by namespace N2 {...}, which is
not
a parent of N1. If he attempts to code:
template<> class N1::Traits<C> { blah blah }
he will get an error saying that he is not allowed to do that.

The only solution I see is to close N2, open N1, write the
specialization, and then close N1 and re-open N2. Yuck, especially if
rather deep in internal namespaces!

Using overloaded functions to return information is easier on the user
who needs to extend it, since the compiler will use argument-dependant
lookup and find his overloaded version of the function. Under some
circumstances the
return type of that function can be used at compile-time to select
from an existing template specialization, but it can't be used to pass
in the type, so it's not a general solution for metaprogramming.

Since the standard library itself has a namespace wrapped around it, I
can't be the first one to notice this! What is the normal approach?

--John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
jakacki
Guest





PostPosted: Tue Oct 12, 2004 10:37 am    Post subject: Re: Use of "traits" templates with namespaces Reply with quote



Quote:
I'm a C++ expert, but have always neglected the area of
templates

So you are not :-)

[...]
Quote:
Suppose my library is in namespace N1. That is, all my
headers with all my global stuff, including templates,
are surrounded by namespace N1 { ... }. In my library I
have a traits template, say Traits<T>. That's actually

N1::Traits<T>.

The user then creates a program, or another library, and
puts all of his stuff in namespace N2. He creates a
class C that he wants to use with my library, so he needs
to define an explicit specialization for N1::Traits<C>.

However, his source file is surrounded by namespace N2
{...}, which is not
a parent of N1. If he attempts to code:
template<> class N1::Traits<C> { blah blah }
he will get an error saying that he is not allowed to do
that.

The only solution I see is to close N2, open N1, write the
specialization, and then close N1 and re-open N2.
[...]
Since the standard library itself has a namespace wrapped
around it, I can't be the first one to notice this! What
is the normal approach?

The one you came up with.

BR
Grzegorz

--
Free C++ frontend library: http://opencxx.sourceforge.net
China from the inside: http://www.staryhutong.com
Myself: http://www.dziupla.net/gj/cv




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
jakacki
Guest





PostPosted: Tue Oct 12, 2004 10:38 am    Post subject: Re: Use of "traits" templates with namespaces Reply with quote



Quote:
I'm a C++ expert, but have always neglected the area of
templates

So you are not :-)

[...]
Quote:
Suppose my library is in namespace N1. That is, all my
headers with all my global stuff, including templates,
are surrounded by namespace N1 { ... }. In my library I
have a traits template, say Traits<T>. That's actually

N1::Traits<T>.

The user then creates a program, or another library, and
puts all of his stuff in namespace N2. He creates a
class C that he wants to use with my library, so he needs
to define an explicit specialization for N1::Traits<C>.

However, his source file is surrounded by namespace N2
{...}, which is not
a parent of N1. If he attempts to code:
template<> class N1::Traits<C> { blah blah }
he will get an error saying that he is not allowed to do
that.

The only solution I see is to close N2, open N1, write the
specialization, and then close N1 and re-open N2.
[...]
Since the standard library itself has a namespace wrapped
around it, I can't be the first one to notice this! What
is the normal approach?

The one you came up with.

BR
Grzegorz

--
Free C++ frontend library: http://opencxx.sourceforge.net
China from the inside: http://www.staryhutong.com
Myself: http://www.dziupla.net/gj/cv




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Alberto Barbati
Guest





PostPosted: Tue Oct 12, 2004 10:44 am    Post subject: Re: Use of "traits" templates with namespaces Reply with quote

John M. Dlugosz wrote:
Quote:
Suppose my library is in namespace N1. That is, all my headers with
all my global stuff, including templates, are surrounded by namespace
N1 { ... }. In my library I have a traits template, say Traits<T>.
That's actually N1::Traits<T>.

The user then creates a program, or another library, and puts all of
his stuff in namespace N2. He creates a class C that he wants to use
with my library, so he needs to define an explicit specialization for
N1::Traits<C>.

However, his source file is surrounded by namespace N2 {...}, which is
not
a parent of N1. If he attempts to code:
template<> class N1::Traits<C> { blah blah }
he will get an error saying that he is not allowed to do that.

Correct. It's because of 14.7.3/2: "An explicit specialization shall be
declared in the namespace of which the template is a member..."

Quote:
The only solution I see is to close N2, open N1, write the
specialization, and then close N1 and re-open N2. Yuck, especially if
rather deep in internal namespaces!

Yes, that's the only solution available now. However, paper N1691
(Explicit namespaces) proposes, among other things, to allow the
template<> class N1::Traits<C> syntax, which sounds quite reasonable to
me. Maybe such a feature is important enough on its own to deserve a
separate proposal.

Alberto

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Michael Kurz
Guest





PostPosted: Tue Oct 12, 2004 9:32 pm    Post subject: Re: Use of "traits" templates with namespaces Reply with quote


"John M. Dlugosz" <11lrhap02 (AT) sneakemail (DOT) com> schrieb im Newsbeitrag
news:78557888.0410102157.9ddc979 (AT) posting (DOT) google.com...
Quote:

But everything I've read ignores the following issue:

Suppose my library is in namespace N1. That is, all my headers with
all my global stuff, including templates, are surrounded by namespace
N1 { ... }. In my library I have a traits template, say Traits<T>.
That's actually N1::Traits<T>.

The user then creates a program, or another library, and puts all of
his stuff in namespace N2. He creates a class C that he wants to use
with my library, so he needs to define an explicit specialization for
N1::Traits<C>.


IMHO I would not use specialization here. As the "traits" concept or as well
the "policy" concept are typically passed to the host template as template
parameter. So If someone wants to provide different traits there is no need
for specialisation. Simply create the traits class (if required subclass
from the existing traits class) and pass it to the host template.

A very popular example for this is writing a string class, which e.g
compares
caseinsensitive, where you would probably write your own version of
"char_traits", named e.g "caseignor_char_traits" (overwriting at least the
eq() function, or whatever you find useful).

typedef std::basic_string<char, caseignor_char_traits std::allocator<char> > no_case_string;



Best Regards
Michael



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
G.J. Giezeman
Guest





PostPosted: Tue Oct 12, 2004 9:34 pm    Post subject: Re: Use of "traits" templates with namespaces Reply with quote

John M. Dlugosz wrote:
Quote:

But everything I've read ignores the following issue:

Suppose my library is in namespace N1. That is, all my headers with
all my global stuff, including templates, are surrounded by namespace
N1 { ... }. In my library I have a traits template, say Traits<T>.
That's actually N1::Traits<T>.

The user then creates a program, or another library, and puts all of
his stuff in namespace N2. He creates a class C that he wants to use
with my library, so he needs to define an explicit specialization for
N1::Traits<C>.

However, his source file is surrounded by namespace N2 {...}, which is
not
a parent of N1. If he attempts to code:
template<> class N1::Traits<C> { blah blah }
he will get an error saying that he is not allowed to do that.

The only solution I see is to close N2, open N1, write the
specialization, and then close N1 and re-open N2. Yuck, especially if
rather deep in internal namespaces!

Using overloaded functions to return information is easier on the user
who needs to extend it, since the compiler will use argument-dependant
lookup and find his overloaded version of the function. Under some
circumstances the
return type of that function can be used at compile-time to select
from an existing template specialization, but it can't be used to pass
in the type, so it's not a general solution for metaprogramming.

Since the standard library itself has a namespace wrapped around it, I
can't be the first one to notice this! What is the normal approach?

You could read the proposal about explicit namespaces by David Abrahams:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1691.html

This paper mentions this problem, current ways of dealing with the
problem and proposes a change in the language to support this better.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Adriano Dal Bosco
Guest





PostPosted: Tue Oct 12, 2004 9:35 pm    Post subject: Re: Use of "traits" templates with namespaces Reply with quote

John M. Dlugosz wrote:

Quote:
However, his source file is surrounded by namespace N2 {...}, which is
not
a parent of N1. If he attempts to code:
template<> class N1::Traits<C> { blah blah }
he will get an error saying that he is not allowed to do that.

Curious behaviour, hum? I never noticed that. Did you try other
compilers? If not, please post the code that produce that error here so
that we can test it.

--

Adriano

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John M. Dlugosz
Guest





PostPosted: Wed Oct 13, 2004 11:31 am    Post subject: Re: Use of "traits" templates with namespaces Reply with quote

"Michael Kurz" <mkurz (AT) move-multimedia (DOT) com> wrote

Quote:
IMHO I would not use specialization here. As the "traits" concept or as well
the "policy" concept are typically passed to the host template as template
parameter. So If someone wants to provide different traits there is no need
for specialisation. Simply create the traits class (if required subclass
from the existing traits class) and pass it to the host template.

A very popular example for this is writing a string class, which e.g
compares
caseinsensitive, where you would probably write your own version of
"char_traits", named e.g "caseignor_char_traits" (overwriting at least the
eq() function, or whatever you find useful).

typedef std::basic_string<char, caseignor_char_traits std::allocator<char> > no_case_string;

I agree that someone can pass a totally unrelated traits class when
giving the traits argument to the template. There is no need for it
to be a specialization of anything previous.

What I'm getting at is not novel traits for an existing type, but
default traits for a new type. To continue the string example, say I
want to make std::char_traits<N2::xwchar_t> that is the normal case
for that class. Anyone creating a std::basic_string<xwchar_t> can
leave off the second argument and get the default that came with the
xwchar_t class itself.

The basic_string template is written to have the default supplied as
an explicit specialization, so without changes to the syntax rules
there seems to be no better way to create such a specialization. But,
is there a better way to create a template with optional arguments
that can have defaults dependant on the main template argument? (I
have one idea; I'll post after I play with it for a few days)

--John

--John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John M. Dlugosz
Guest





PostPosted: Wed Oct 13, 2004 11:34 am    Post subject: Re: Use of "traits" templates with namespaces Reply with quote

Adriano Dal Bosco <email (AT) account (DOT) net> wrote

Quote:
John M. Dlugosz wrote:

However, his source file is surrounded by namespace N2 {...}, which is
not
a parent of N1. If he attempts to code:
template<> class N1::Traits<C> { blah blah }
he will get an error saying that he is not allowed to do that.

Curious behaviour, hum? I never noticed that. Did you try other
compilers? If not, please post the code that produce that error here so
that we can test it.

If you've not had any trouble, it's because you're not writing the new
code inside a namespace. So you're in the root namespace. If memory
serves, you can use the syntax I showed only in a parent of N1. So
you're in a parent of std:: and everything else, so it worked fine.

I only tried my examples on VC++ 7.1. But I researched the language
in the standard and I know it's "incorrect" by fiat.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John M. Dlugosz
Guest





PostPosted: Tue Oct 19, 2004 4:47 pm    Post subject: Re: Use of "traits" templates with namespaces Reply with quote

[email]11lrhap02 (AT) sneakemail (DOT) com[/email] (John M. Dlugosz) wrote in message

Quote:
The basic_string template is written to have the default supplied as
an explicit specialization, so without changes to the syntax rules
there seems to be no better way to create such a specialization. But,
is there a better way to create a template with optional arguments
that can have defaults dependant on the main template argument? (I
have one idea; I'll post after I play with it for a few days)

I got something that works well and is nice to use. I'll post details
after I write it up.

--John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.