Topic: Using local type as template argument


Author: Anand Hariharan <mailto.anand.hariharan@gmail.com>
Date: Wed, 18 Jul 2007 10:41:05 CST
Raw View
I have an inline function in a header file that impacts several
translation units.

Within this function, I need to use the map functionality that used
several types as a key.  When I tried to create an ad-hoc struct that
included all these types, (within the scope of this inline function),
implemented a < operator as its member function for it and used it as
a key for the map, compilation failed.

My questions:

1. What is the rationale for 14.3 - 9?  Is it a compiler technology
issue, or is it a restriction by design?  If the former, is this
restriction likely to be removed in the foreseeable future?

2. How do you suggest I go about resolving my problem?  Needless to
say, creating this ad-hoc structure outside my inline function will
make it appear in all those TUs, which I would like to avoid. Using
map of map of map of map of map is ugly.

thank you for listening,
- Anand Hariharan

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: cbarron413@adelphia.net (Carl Barron)
Date: Thu, 19 Jul 2007 01:36:12 GMT
Raw View
In article <1184772926.569688.183720@x35g2000prf.googlegroups.com>,
Anand Hariharan <mailto.anand.hariharan@gmail.com> wrote:

> I have an inline function in a header file that impacts several
> translation units.
>
> Within this function, I need to use the map functionality that used
> several types as a key.  When I tried to create an ad-hoc struct that
> included all these types, (within the scope of this inline function),
> implemented a < operator as its member function for it and used it as
> a key for the map, compilation failed.
> \uggest I go about resolving my problem?  Needless to
> say, creating this ad-hoc structure outside my inline function will
> make it appear in all those TUs, which I would like to avoid. Using
> map of map of map of map of map is ugly.
>

   A template parameter must have external linkage and local types have
no linkage.
   The simplest approach is to give the local type external linkage but
inaccessable outside of a class. {nested types of private access have
external linkage.}  Making the function a functor fairly
easy the class has private nested types, and an operator () (/*
function args */).

class foo_class
{
   struct my_key
   {
      //...
   };
public:
   void operator () (/* args */)
   {
      /* body of foo with out the local type my_key's definition */
   }
};

void foo(/* args */)
{
   foo_class()(/* copy args as actual params */)
}

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Thu, 19 Jul 2007 03:41:17 GMT
Raw View
Anand Hariharan ha scritto:
> 1. What is the rationale for 14.3 - 9?  Is it a compiler technology
> issue, or is it a restriction by design?  If the former, is this
> restriction likely to be removed in the foreseeable future?

There is no such thing as 14.3 - 9 in the standard. I guess you are
referring to 14.3.1/2. "A local type, a type with no linkage, an unnamed
type or a type compounded from any of these types shall not be used as a
template-argument for a template type-parameter."

I guess the main problem is that in all listed cases it's not possible
to obtain a name that can globally and uniquely identify the type. If
you can't get such name, then you can't mangle a meaningful name for the
template specialization that uses it either. However, a template
specialization always have linkage, so it must have a global unique name.

I don't think this restriction is going to be relaxed in the future.

> 2. How do you suggest I go about resolving my problem?  Needless to
> say, creating this ad-hoc structure outside my inline function will
> make it appear in all those TUs, which I would like to avoid. Using
> map of map of map of map of map is ugly.

What about:

class /* a meaningful name here */
{
   template <....>
   /* definition of your ugly type here */

public:
   template <...>
   static /* your function that uses the ugly type */
};

the type will have linkage, but won't be accessible outside your
function because it is private to a class. If you don't like the ::
notation to call your function, then you might use a friend declaration
of a free function instead.

HTH,

Ganesh

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: Mathias Gaunard <loufoque@gmail.com>
Date: Thu, 19 Jul 2007 14:35:48 CST
Raw View
On Jul 18, 6:41 pm, Anand Hariharan <mailto.anand.hariha...@gmail.com>
wrote:

> 2. How do you suggest I go about resolving my problem?  Needless to
> say, creating this ad-hoc structure outside my inline function will
> make it appear in all those TUs, which I would like to avoid. Using
> map of map of map of map of map is ugly.

std::tr1::tuple ?


---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Thu, 19 Jul 2007 15:00:54 CST
Raw View
On 19 Jul., 05:41, AlbertoBarb...@libero.it (Alberto Ganesh Barbati)
wrote:
> I guess the main problem is that in all listed cases it's not possible
> to obtain a name that can globally and uniquely identify the type. If
> you can't get such name, then you can't mangle a meaningful name for the
> template specialization that uses it either. However, a template
> specialization always have linkage, so it must have a global unique name.

So and so. Actually I guess that it is possible to do that with
current
existing technology and would like to hear the statement of a compiler
writer.
First, we already have unnamed namespaces [namespace.unnamed], which
provide a guaranteed globally unique "prefix" (AKA qualification) per
translation unit. Members of these namespaces do have external
linkage.
Depending on the unspecified creation scheme of these uniquely names
one
could think of some base-offset scheme to create globally unique names
for
local types, e.g. "unique"_0 for the first local type in the TU,
"unique"_1 for the
second, etc if "unique" corresponds to the unique name of the current
unnamed
namespace. There exist some hidden assumption to make that work, but
it
would always work, if the separator between the base and the offset is
some
character which is no legal character according to the standard words
(e.g. @
or |).

> I don't think this restriction is going to be relaxed in the future.

You are probably right.

Greetings from Bremen,

Daniel

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: Alberto Ganesh Barbati <AlbertoBarbati@libero.it>
Date: Thu, 19 Jul 2007 23:48:31 CST
Raw View
Daniel Kr  gler ha scritto:
>
> So and so. Actually I guess that it is possible to do that with
> current
> existing technology and would like to hear the statement of a compiler
> writer.
> First, we already have unnamed namespaces [namespace.unnamed], which
> provide a guaranteed globally unique "prefix" (AKA qualification) per
> translation unit. Members of these namespaces do have external
> linkage.
> Depending on the unspecified creation scheme of these uniquely names
> one
> could think of some base-offset scheme to create globally unique names
> for
> local types, e.g. "unique"_0 for the first local type in the TU,
> "unique"_1 for the
> second, etc if "unique" corresponds to the unique name of the current
> unnamed
> namespace. There exist some hidden assumption to make that work, but
> it
> would always work, if the separator between the base and the offset is
> some
> character which is no legal character according to the standard words
> (e.g. @
> or |).

With such scheme you may handle names that are local to regular
functions, but what about names that are local to a function template?
The point of instantiation can be in different TUs. I'm not saying that
it can't be done, but it seems a formidable task to me.

Ganesh

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: Anand Hariharan <mailto.anand.hariharan@gmail.com>
Date: Fri, 20 Jul 2007 09:29:20 CST
Raw View
On Jul 18, 10:41 pm, AlbertoBarb...@libero.it (Alberto Ganesh Barbati)
wrote:
> Anand Hariharan ha scritto:
>
> > 1. What is the rationale for 14.3 - 9?  Is it a compiler technology
> > issue, or is it a restriction by design?  If the former, is this
> > restriction likely to be removed in the foreseeable future?
>
> There is no such thing as 14.3 - 9 in the standard. I guess you are
> referring to 14.3.1/2. "A local type, a type with no linkage, an unnamed
> type or a type compounded from any of these types shall not be used as a
> template-argument for a template type-parameter."
>

I must have an outdated copy of the standard.  FWIW, the text you
reproduced above is identical to the 9th clause in section 14.3 in the
copy that I have.

> I guess the main problem is that in all listed cases it's not possible
> to obtain a name that can globally and uniquely identify the type. If
> you can't get such name, then you can't mangle a meaningful name for the
> template specialization that uses it either. However, a template
> specialization always have linkage, so it must have a global unique name.
>

I am not trying to specialize any template, just instantiating one.

> I don't think this restriction is going to be relaxed in the future.
>
> > 2. How do you suggest I go about resolving my problem?  Needless to
> > say, creating this ad-hoc structure outside my inline function will
> > make it appear in all those TUs, which I would like to avoid. Using
> > map of map of map of map of map is ugly.
>
> What about:
>
> class /* a meaningful name here */
> {
>    template <....>
>    /* definition of your ugly type here */
>
> public:
>    template <...>
>    static /* your function that uses the ugly type */
>
> };
>
> the type will have linkage, but won't be accessible outside your
> function because it is private to a class. If you don't like the ::
> notation to call your function, then you might use a friend declaration
> of a free function instead.
>

Which still introduces a name in a header file used by multiple TUs.

- Anand

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Fri, 20 Jul 2007 14:25:11 CST
Raw View
On 20 Jul., 07:48, Alberto Ganesh Barbati <AlbertoBarb...@libero.it>
wrote:
> With such scheme you may handle names that are local to regular
> functions, but what about names that are local to a function template?
> The point of instantiation can be in different TUs. I'm not saying that
> it can't be done, but it seems a formidable task to me.

I don't think that this task is more fomidable than the already
necessary
task to eliminate all multiple equivalent instantiations of the
function
template but one. The relevance to provide a name for linkage
purposes
starts with the instantiation, there is no need to do that before.
*Iff*
instantiation is done in any TU, the corresponding POI's have a
proper
ordering relative to other entities and the discussed base-offset
scheme
should work for each local name of these instantiations.
Later on, the already necessary elimination task is done such that
only
one remains.
Note that this does also not lead to problematic situations, if
multiple
instantiations of the *same* function template occur in the *same*
TU:
For each (preliminary) instantiation the nameing scheme is applied
for
the corresponding local named entities (they will be different, of
course),
but finally the linker will remove all duplicates such that only one
of
them remains. Because of this elimination task there is effectively
no
violation of the ODR - the above mentioned temporary different names
for
seemingly same (virtual) entities are only an artifact of a single
step
of the complete process, but this problem does no longer exist after
this. IMO this procedure should even work in case of local names of
*static* function templates, because of the uniqueness constraint on
the unspecified base part of the name (which has the same properties
as the artifical (hidden) name of an unnamed namespace. But if there
really exist implementor objections in this situation I would not
hesitate
to explicitly forbid the support of external linkage of local names
in
static function templates...

What do you think?

Greetings,

Daniel

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: cbarron413@adelphia.net (Carl Barron)
Date: Sat, 21 Jul 2007 09:53:22 GMT
Raw View
In article <1184940625.009654.295650@g4g2000hsf.googlegroups.com>,
Anand Hariharan <mailto.anand.hariharan@gmail.com> wrote:

>
> >
> > the type will have linkage, but won't be accessible outside your
> > function because it is private to a class. If you don't like the ::
> > notation to call your function, then you might use a friend declaration
> > of a free function instead.
> >
>
> Which still introduces a name in a header file used by multiple TUs.
   If that is more important than making function inlinable, I don't
see the problem.  If inlining the function is no a major consideration
then just placing the wrapper class or the local types in an unnamed
namespace in the implementation file solves the problem of other TU's
seeing any thing but the prototype of the function itself.

   I have not seen any great arguments to allow local types as template
parameters, that these workarounds do not cover.  [except inlining a
complex function, which a compiler is unlikely to do anyway]

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: Greg Herlihy <greghe@pacbell.net>
Date: Sat, 21 Jul 2007 20:22:35 CST
Raw View
On Jul 19, 10:48 pm, Alberto Ganesh Barbati <AlbertoBarb...@libero.it>
wrote:
>
> With such scheme you may handle names that are local to regular
> functions, but what about names that are local to a function template?
> The point of instantiation can be in different TUs. I'm not saying that
> it can't be done, but it seems a formidable task to me.

At least two C++ compilers already offer support for local types as
template type arguments. And as N2187 makes clear - adding this
ability to the C++ languagee (so that every C++09 compiler would
support it) does not appear to be a formidable task at all:

    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2187.pdf

Greg



---
[ 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.comeaucomputing.com/csc/faq.html                      ]