WG21 paper on templated namespaces

K

kwikius

Hi all,

I have been searching through the list of papers at:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/

I seem to remember a proposal regarding templated namespaces e.g:

template <typename T>
namespace X{

}

Unfortunately I cant find it. Does anyone know the name/number of the
paper I'm thinking of or have I just invented it?

regards
Andy Little
 
V

Victor Bazarov

kwikius said:
[..]
I seem to remember a proposal regarding templated namespaces e.g:

template <typename T>
namespace X{

}
[..]

What is it supposed to do?

V
 
K

kwikius

Victor said:
kwikius said:
[..]
I seem to remember a proposal regarding templated namespaces e.g:

template <typename T>
namespace X{

}
[..]

What is it supposed to do?

I sometimes use a struct for grouping stuff to help in source code
legibility and to save typing:

template <typename T>
struct length{
typedef something_ugly<T,...> mm;
typedef somethingelse_ugly<T,...> m;
};

// declare a something_ugly
length<double>::mm mylength;

The problem with a struct is you cant reopen it, which would be a
desirable feature. Maybe I want to add inches:

template<typename T>
namespace length{
typedef something_else_again<T,...> in;
}

length<double>::in mylength1;

I thought I had seen i a paper about this, but cant find it now. Does
anyone know what I'm talking about? (hmm do I really want these guys to
answer that? ... ;-) )

regards
Andy Little
 
V

Victor Bazarov

kwikius said:
Victor said:
kwikius said:
[..]
I seem to remember a proposal regarding templated namespaces e.g:

template <typename T>
namespace X{

}
[..]

What is it supposed to do?

I sometimes use a struct for grouping stuff to help in source code
legibility and to save typing:

template <typename T>
struct length{
typedef something_ugly<T,...> mm;
typedef somethingelse_ugly<T,...> m;
};

// declare a something_ugly
length<double>::mm mylength;

The problem with a struct is you cant reopen it, which would be a
desirable feature. Maybe I want to add inches:

template<typename T>
namespace length{
typedef something_else_again<T,...> in;
}

length<double>::in mylength1;

Now, tell me, why can't you add inches to the original struct?

Namespaces have a certain purpose. Mostly it's to prevent name collisions
and not save typing or grouping for legibility's sake.
I thought I had seen i a paper about this, but cant find it now. Does
anyone know what I'm talking about? (hmm do I really want these guys
to answer that? ... ;-) )

Try asking in 'comp.std.c++', though.

V
 
K

kwikius

Now, tell me, why can't you add inches to the original struct?

Its a library. I can't know all the units a user might want to make use
of.
Namespaces have a certain purpose. Mostly it's to prevent name collisions
and not save typing or grouping for legibility's sake.

Sure thats your moral position. OTOH I find it convenient to use a
struct for grouping and save typing. Member typedefs are a well known
idiom for traits classes for example.

A namespace is reopenable which is a useful feature it has over a
struct.
Try asking in 'comp.std.c++', though.

Yes. I was hoping someone might give me an instant answer though!

regards
Andy Little
 
K

kwikius

Victor said:
kwikius said:
[..]
A namespace is reopenable which is a useful feature it has over a
struct.

You can always *derive* from a struct, can't you?

Yes. The current solution seems to be to derive the library struct (
'length' above) from a (by default empty) struct allocated to the user,
but a templated namespace would be superior I think.

FWIW its a major idiom in my physical quantities library pqs, which
should help explain why I want to do it this particular way for those
interested.

http://tinyurl.com/7m5l8

regards
Andy Little
 
K

Kaz Kylheku

kwikius said:
Its a library. I can't know all the units a user might want to make use
of.


Sure thats your moral position. OTOH I find it convenient to use a
struct for grouping and save typing. Member typedefs are a well known
idiom for traits classes for example.

A namespace is reopenable which is a useful feature it has over a
struct.

So given that it's reopenable, how would you instantiate a namespace
template? Piece by piece, I suppose: instantiate those parts that are
visible.

I could see it being a shorthand that could save a lot of repetitive
template syntax. E.g.

template <typename T> namespace N {
int foo(const T &);
}

Here, uses of the template ID N::foo without template arguments would
deduce T.

Would this be allowed?

template <typename T> namespace N {
void foo(); // no arguments
}

Here, nothing in the foo type signature depends on T. But foo could
refer to T things in the namespace.

template <typename T> namespace N {
T t;
void reset() { T = 0; }
}

I suppose it's similar to a class with a static member and static
function:

template <typename T> class C {
public:
static T t;
static void reset() { t = 0; }
};

int C<int>::t;

int main()
{
C<int>::reset();
return 0;
}

Basically, here we are just using the class as a namespace, right? It
has only static members. We never instantiate the class. Instantiation
of the template is forced by the definition of the static member.

You have to repeat that definition for every type.

The template namespace could do away with that inconvenience, since the
namespace could enclose a definition. But then that definition would
have to be in scope in order to be implicitly instantiated.

Classes are different from namespaces because they separate the
declaration from the implementation. The entire declaration is visible
at once. Where it's not visible, the class is not known. A namespace is
not necessarily all visible at once. Moreover, if a function has a body
in a class declaration, it's an inline function, which is not true of
namespaces. A namespace can contain noninline functions.

So there would have to be some special rules for namespace template
instantiation, such as: 1) instantiate just the necessary parts, from
whatever part of the templated namespace that is visible, and place the
instantiations into the translation unit where the reference is made.
Full function and object definitions are instantiated automatically if
implicit instantiation takes place. If only declarations are visible,
they are instantiated, but the definitions are not.

E.g.


// File1.cc

template <type T> namespace N {
int def_obj = 0;

extern int decl_obj;

int def_fun()
{
return def_obj + decl_obj;
}

int decl_fun();

int foo;
}

// ...

N::def_fun(); // error, ambiguous

N<int>::def_fun();
// requests N<int>::def_fun() instantiation.
// also requests N<int>::def_obj instantiation, needed by the body.
// also requests N<int>::decl_obj instantiation, but that is just a
decl
// so this won't link unless N<int>::decl_obj is generated somewhere.

N<int>::decl_fun();
// "instantiates" the declaration, but a definition must be
// made somewhere.

Now suppose there is a second file:

// File2.cc

template <typename T> namespace N {
int decl_obj = 42;
}

// alternate syntax; must use template arguments on N

template <typename T>
int N<T>::decl_fun()
{
return decl_obj;
}

// now we must force instantiation somehow.

// How about explicit request?
// Generates over all /visible/ N<T>.
// E.g. does not generate N<int>::foo since
// N<T>::foo is declared in the other translation unit,
// which is not known here.

template namespace N<int>;
 
F

Frederick Gotham

Kaz Kylheku posted:

I could see it being a shorthand that could save a lot of repetitive
template syntax. E.g.

template <typename T> namespace N {
int foo(const T &);
}



I like this! We could then have code like the following:

template<class T> namespace N {

int Compare( const T *, const T * )
{
// ...
}

T* Concantenate( const T *, const T * )
{
// ...
}

}


void ArbitraryFunc()
{
using namespace N<wchar_t>;

const wchar_t *p1 = L"First";
const wchar_t *p2 = L"Second";

Compare( p1, p2 );

Concantenate( p1, p2 );
}
 
K

kwikius

Hi Kaz,

FWIW I posted your post separately to comp.std.c++ (rather than cross
posting)

regards
Andy Little
 
K

kwikius

Victor said:
kwikius said:
[..]
A namespace is reopenable which is a useful feature it has over a
struct.

You can always *derive* from a struct, can't you?

BTW another important property of a namespace is that you cant't
instantiate it. IOW used as a container a struct has inconvenient
connotations requiring extra work to prevent instantions (e.g deriving
from boost::noncopyable which causes its own problems) . IOW its a pain
in th a** using a struct this way.

regards
Andy Little
 
K

kwikius

kwikius said:
Hi Kaz,

FWIW I posted your post separately to comp.std.c++ (rather than cross
posting)

At least I thought I had. If nothing appears on comp.std.c++ in the
next day or so, I'll try again.

regards
Andy Little
 
A

Alf P. Steinbach

* kwikius:
At least I thought I had. If nothing appears on comp.std.c++ in the
next day or so, I'll try again.

The comp.std.c++ robo-moderator software is currently acting up.
Sometimes it acts like a black hole. Sometimes it forwards the message
to two moderators, one of which will approve it, and one of which will
reject it on the grounds that it's very, almost suspiciously similar to
the one approved. And so on. So it's probably no fault of yours if
that message seemingly disappears: just try again.
 
K

kwikius

Alf said:
* kwikius:

The comp.std.c++ robo-moderator software is currently acting up.
Sometimes it acts like a black hole. Sometimes it forwards the message
to two moderators, one of which will approve it, and one of which will
reject it on the grounds that it's very, almost suspiciously similar to
the one approved. And so on. So it's probably no fault of yours if
that message seemingly disappears: just try again.

Ok. Its there!

regards
Andy Little
 
K

kwikius

Hi Frederick,

Frederick said:
I like this! We could then have code like the following:

[snip details]

Its probably worth re-posting your post to comp.std.c++ FWIW, in the
thread with the same title as this one.

Sorry if I'm stating the blindingly obvious!

regards
Andy Little
 
K

Kaz Kylheku

kwikius said:
Hi Frederick,

Frederick said:
I like this! We could then have code like the following:

[snip details]

Its probably worth re-posting your post to comp.std.c++ FWIW, in the
thread with the same title as this one.

There is no point in doing that. You will invariably be told:

``Wonderful! Now all you have to do is produce a working reference
implementation
in at least one compiler, get some users and spend some time gaining
experience
with the use of that feature.''

So it ultimately doesn't matter where in Usenet you want to discuss it,
as long as it's not too wildly off topic wherever that is.

:)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top