Topic: litteral string as template parameter


Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Fri, 17 Sep 1993 07:42:34 GMT
Raw View
In article <26564@alice.att.com> ark@alice.UUCP () writes:
>Would someone mind explaining to me why having string literals as
>template parameters is useful?

I am glad to see that some other respondants have answered this (very
reasonable and legitimate) question.

--

-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Fri, 17 Sep 1993 07:53:40 GMT
Raw View
In article <1993Sep15.203542.26334@vedge.com> hendrik@vedge.com (Hendrik Boom) writes:
>rfg@netcom.com (Ronald F. Guilmette) writes:
>: In article <KANZE.93Sep10121617@slsvhdt.us-es.sel.de> kanze@us-es.sel.de (James Kanze) writes:
>:
>: >Actually, I think the issue is less clear than I present it.  An array
>: >only degenerates to a pointer in certain well defined contexts; is
>: >template instantiation one of these?  Section 8.2.4 of the ARM states
>: >that: "When an identifier of array type appears in an expression,
>: >except as the operand of sizeof or & or used to initialize a
>: >reference, it is converted into a pointer to the first member of the
>: >array."  In the absence of any other specifications, I would interpret
>: >this as saying yes, an array does degenerate into a pointer when used
>: >for template instantiation.
>:
>: I would agree.  Note however that this point only implies that *if* string
>: literals were allowed as template actual instantiation arguments, then
>: such an argument would have to be matched by a corresponding template
>: formal (non-type) parameter declared to have type `char*'.  (On this
>: point I think everyone would agree.)
>
>Not everyone.  I still prefer char[].

This is an interesting (and also rather subtle) point.

I raised the question (which was later incorporated onto John Spicer's
list of open template issues for x3j16) as to whether or not the *apparent*
types of template formal non-type parameters should be considered to decay
in the same way as formal parameter types for functions do.

Unless I am mistaken, this was discussed at the last x3j16 meeting and
(I think) it was decided that the types of template formal non-type
parameters do indeed decay just as function formal parameter types do.
Thus, the following declarations are equivalent:

 template <char arg1[], void foo (int)> class TMPL;

 template <char *arg1, void (*foo) (int)> class TMPL;

--

-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------




Author: ross@utopia.druid.com (Ross Ridge)
Date: Thu, 16 Sep 1993 22:22:26 GMT
Raw View
pete@borland.com (Pete Becker) writes:
> So far the two responses to Andy's question have both involved
>displaying the name of a class. Since RTTI gives you this capability I don't
>find these examples particularly helpful. I can do the same thing much more
>directly...

Unfortunately since I don't have access to the in-house version of your
compiler, I'm stuck using the release version.  RTTI isn't too helpful
to me and I don't imagine it will be for a least a year or two.

       Ross Ridge





Author: pete@borland.com (Pete Becker)
Date: Fri, 17 Sep 1993 18:15:28 GMT
Raw View
In article <1993Sep16.222226.27572@utopia.druid.com>,
Ross Ridge <ross@utopia.druid.com> wrote:
>pete@borland.com (Pete Becker) writes:
>> So far the two responses to Andy's question have both involved
>>displaying the name of a class. Since RTTI gives you this capability I don't
>>find these examples particularly helpful. I can do the same thing much more
>>directly...
>
>Unfortunately since I don't have access to the in-house version of your
>compiler, I'm stuck using the release version.  RTTI isn't too helpful
>to me and I don't imagine it will be for a least a year or two.

 The question was about what the language should support, not about
what any particular implementation currently supports. RTTI provides a simpler
and more maintainable solution to the problem that both responses mentioned.
 If you have a compiler that allows literal strings as template
parameters, fine, use it. But don't expect that code to be portable, since
that usuage is currently illegal. And be sure that you understand the
semantics that that particular compiler provides for such usage, because you're
not going to be able to read about it in any of the standard texts.
 -- Pete







Author: dan@snap.prds.cdx.mot.com (Dan Breslau)
Date: Sat, 18 Sep 1993 19:51:20 GMT
Raw View
pete@borland.com (Pete Becker) writes:
[...]

> If you have a compiler that allows literal strings as template
>parameters, fine, use it. But don't expect that code to be portable, since
>that usuage is currently illegal. And be sure that you understand the
>semantics that that particular compiler provides for such usage, because you're
>not going to be able to read about it in any of the standard texts.
> -- Pete

Illegal, or simply unsupported?  I cited Stroustrup in an earlier post
to show that at least one reliable source claimed it was legal.
--
Dan Breslau          dan@codex.com

Freude!




Author: ross@utopia.druid.com (Ross Ridge)
Date: Sun, 19 Sep 1993 01:19:08 GMT
Raw View
pete@borland.com (Pete Becker) writes:
> The question was about what the language should support, not about
>what any particular implementation currently supports.

No, the question asked was:

 Would someone mind explaining to me why having string
 literals as template parameters is useful?

Asking if an extension is *useful* is not the same thing as asking
what the language *should* support.

> If you have a compiler that allows literal strings as template
>parameters, fine, use it. But don't expect that code to be portable, since
>that usuage is currently illegal.

So what?  It's just as portable and just as illegal to use RTTI.

> And be sure that you understand the semantics that that particular
>compiler provides for such usage, because you're not going to be able
>to read about it in any of the standard texts.

Not being able to see into the future, I'm just as unable to see what
the semantics (or for that matter the syntax) of RTTI will be.

Perhaps RTTI would make allowing string literals as template
parameters an unnecessary extension to the language, but this
point is moot.  The existing ability to use the address an array
of chars as a template parameter already makes it an unnecessary
extension.  However this doesn't mean that this extension wouldn't
be convenient and useful.

      Ross Ridge





Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sun, 19 Sep 1993 19:24:34 GMT
Raw View
In article <26564@alice.att.com> ark@alice.UUCP () writes:
>Would someone mind explaining to me why having string literals as
>template parameters is useful?
>
>I see why it's useful to have integers: it allows things like this:
>
> template<class T, size_t size> class Buffer {
>  // ...
>  T buf[size];
>  // ...
> };
>
>which avoids the overhead of dynamically allocating buf separately.
>This works because `size' is a constant expression, which in turn works
>because integral template parameters are constant expressions.
>
>But string literals are never constant expressions, which makes this
>technique irrelevant.  So what good are they?

 My first attempt to use templates used string literals.
I discovered the hard way it didnt work. I replaced this:

 template<char *s> class foo ...

 foo<"Hearts"> ...

with this:

 template<class T> class foo ..

 class Hearts{};
 foo<Hearts> ...

That works fine. <It'll work even better when we get namespaces>

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: jimad@microsoft.com (Jim Adcock)
Date: 20 Sep 93 19:03:39 GMT
Raw View
In article <rfgCDHn9G.M67@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
|Unless I am mistaken, this was discussed at the last x3j16 meeting and
|(I think) it was decided that the types of template formal non-type
|parameters do indeed decay just as function formal parameter types do.
|Thus, the following declarations are equivalent:
|
| template <char arg1[], void foo (int)> class TMPL;
|
| template <char *arg1, void (*foo) (int)> class TMPL;

Boy, I hope not, because this would imply that:

 template <double v[3]> class vec3;
 template <double v[4]> class vec4;

would decay to the same template.  Thus it would not be possible
to specialize and optimize to specific small vector and matrix classes,
or other small allocations.  Or do I misunderstand?  Note that in
the function case arrays *do not* necessarily suffer a decay:

 typedef double V100[100];
 void example(const V100& v100)
 {
  ....
 }

the parm v100 has type 'ref to array of 100' and thus has not
suffered the typical decay to 'ptr to double'.

????




Author: mat@mole-end.matawan.nj.us
Date: Mon, 20 Sep 1993 17:50:42 GMT
Raw View
In article <dan.748381880@snap>, dan@snap.prds.cdx.mot.com (Dan Breslau) writes:
> pete@borland.com (Pete Becker) writes:
> [...]

> > If you have a compiler that allows literal strings as template
> >parameters, fine, use it. But don't expect that code to be portable, since
> >that usuage is currently illegal. And be sure that you understand the
> >semantics that that particular compiler provides for such usage, because
> >you're not going to be able to read about it in any of the standard texts.
> > -- Pete

> Illegal, or simply unsupported?  I cited Stroustrup in an earlier post
> to show that at least one reliable source claimed it was legal.

There's an excellent chance that ANSI will specifically make it illegal.
--
 (This man's opinions are his own.)
 From mole-end    Mark Terribile

 mat@mole-end.matawan.nj.us, Somewhere in Matawan, NJ




Author: pete@borland.com (Pete Becker)
Date: Mon, 13 Sep 1993 17:54:40 GMT
Raw View
In article <9325613.13255@mulga.cs.mu.oz.au>,
Fergus James HENDERSON <fjh@munta.cs.mu.OZ.AU> wrote:
>pete@borland.com (Pete Becker) writes:
>
>>In article <rfgCD4Koy.JLz@netcom.com>,
>>Ronald F. Guilmette <rfg@netcom.com> wrote:
>>>
>>>I don't remember anymore if Pete even gave us his interpretation regarding
>>>the question of the sameness of the types.
>>
>> I didn't. I'd rather watch the discussion develop.
>>
>>>
>>>(My point was that if this *were* to be allowed, sometime in the future,
>>>then I, for one, would want the type rules to be such that `Foo<"arg">'
>>>meant the same thing wherever you wrote it.  I don't believe that any
>>>other choice would be reasonable.)
>>>
>>
>> What about these two? Is there a simple rule that's reasonably
>>intuitive to C programmers moving to C++?
>>
>> template <const char *name> class Foo;
>>
>> Foo<"arg"> f1;
>>
>> const char *cp = "arg";
>> Foo<cp> f2;
>
>This one is illegal, surely, because `cp' is not a compile-time constant
>expression.  You would need to write
>

 Yes, of course. Assuming this change, what should the result be?

> const char * const cp = "arg";
>       ^^^^^
> Foo<cp> f2;
>
>instead, I believe.
>




Author: jamshid@emx.cc.utexas.edu (Jamshid Afshar)
Date: 14 Sep 1993 03:49:12 -0500
Raw View
In article <rfgCD31Fu.746@netcom.com>,
Ronald F. Guilmette <rfg@netcom.com> wrote:
>It is quite apparent that implementations *can* and implementations *do*
>permit actual template arguments corresponding to template non-type formal
>arguments to be constants (as allowed by the rule at the very bottom of
>page 343 of the ARM) and so given the fact that a string literal (such
>as "hello") decays into a pointer constant, I don't really see why anyone
>would claim that it would be harder for implementations to support this
>kind of constant (as a template actual) than it would be for implementations
>to support other kinds of constants.

ARM 14.2 (and the June WP) says that "Other template-args must be
constant-expressions, addresses of objects or functions with external
linkage, or of static class members".  A constant-expression (see
5.19) can only be integral.  The fact that string literals decay to
"pointer constants" is completely irrelevant -- they're neither
constant-expressions nor do they have external linkage.  Btw, unless
ANSI/ISO changes these rules, even floating-point constants and the
address of member functions will continue to be illegal template-args
(I didn't know they were explicitly illegal -- there goes one Borland
bug I've reported).

 template<double d> class Foo {/*..*/};  // impossible to instantiate
 Foo<1.2> f; // error: 1.2 is not a "constant-expression"

 template<void(Shape::*mfp)(int)>  // error
 class Callback {/*...*/};
 Callback<&Shape::rotate> cb;  // error

I'm not exactly sure why only integral constants are allowed or
whether this might be relaxed.  Maybe they don't want compilers to be
required to do floating-point arithmetic at compile-time, and maybe
there's some problems with uniqueness and the address of virtual
functions.

>[...]  Why not just take the value of the characters
>of the string literal themselves and somehow mangle those in as part of the
>process of creating the mangled names for the various template instances?
>I believe that would work.  Then we *could* use string literals as template
>actuals!

You (and lots of other people) are confusing the semantics of a
`char*' template argument.  Remember that in:

 template<const char* name> class Foo {/*...*/}

`name' is a "pointer to a char", not a "string" nor necessarily a
pointer to an array of characters.  It's intended to be instantiated
with the "address of a global".  Even if Foo is instantiated with the
address of an array, it might not be '\0'-terminated or it's values
might not be accessible at compile-time.

 char c = 'A';
 char a[] = { 5, 3, 2, 9 };
 extern char b[];  // defined in other module
 int main() {
    Foo<&c> f1;
    Foo<&a> f2;
    Foo<&b> f3;
    //...
 }

There's no way to specify that a template argument must be an "array
constant" (ie, a string literal).  The implementation you're
suggesting would be like requiring Bar<a> to be the same type as
Bar<b> for the following definitions:

 template<const int* p> class Bar {/*...*/};
 int a[] = { 1, 2, 3 };
 int b[] = { 1, 2, 3 };

This isn't a problem with linker implementations; it's just that
arrays (which is all string literals are) are not first-class types.

We could hop the train to the land of make-believe and invent an
"array constant" syntax for template arguments:

 template<char s[]> class Goo {   // pretend
    // `s' is real array -- don't confuse a template-arg array
    // with an array in function parameter list (which would
    // be almost equivalent to a `char*')
    static size_t nelem() {
       return sizeof(c)/sizeof(char);  // sizeof(c)!=sizeof(char*)
    }
    //...
 }

Then, all Goo<"Hello"> instantiations would be equivalent because the
char array *elements* would be what determines the uniqueness of
template instantiations.  The following two would be illegal, though:

 char str[] = "hello";
 Goo<str> g1;  // error: `str' not an array constant

 char* p = "hello";
 Goo<p> g2;    // error: `p' is not an array

Goo<str> would be illegal for the same reason the following is illegal:

 template<int SZ> class Moo {/*...*};
 int i;
 Moo<i> m;  // error

ARM 7.1.6 discusses "const arrays" but I'm not exactly sure what they are.

 typedef char Str[];   // any way to declare without typedef?
 const Str str2[] = "hello";  // what kind of linkage?
 Goo<str2> g3; // legal and same type as Goo<"Hello"> (?)

If const arrays are required to be initialized (ie, they can't be
extern), then I guess they could be used like the string literals
above:

 template<int a[]> class Poo {/*...*};  // pretend
 typedef int Array[3];
 const Array ka = { 1, 2, 3 };
 const Array kb = { 1, 2, 3 };
 // Poo<ka> is equivalent to Poo<kb>

Actually, I just realized that the implementation Ronald describes is
possible even without array-constant template arguments if compilers
are required to treat Foo<"Hello"> differently than Foo<&global>.
Foo<string-literal> or Foo<const-array> would "mangle" to something
using the array elements (eg, hash them to a unique value):
Foo__73213.  Foo<address-of-global> would mangle to Foo__global.

This would require a fairly significant change to 14.2, and I would
expect floating-point constants and the address of member functions to
be allowed as template arguments along with a change like this.  I'm
not sure I would like this extension, though.  A `char*' template
argument will then not "really" be a pointer to a char.  I might even
prefer the const array template-arg extension I discuss above because
it's more explicit about what's going on.

Jamshid Afshar
jamshid@emx.cc.utexas.edu





Author: ark@alice.att.com (Andrew Koenig)
Date: 14 Sep 93 14:20:31 GMT
Raw View
Would someone mind explaining to me why having string literals as
template parameters is useful?

I see why it's useful to have integers: it allows things like this:

 template<class T, size_t size> class Buffer {
  // ...
  T buf[size];
  // ...
 };

which avoids the overhead of dynamically allocating buf separately.
This works because `size' is a constant expression, which in turn works
because integral template parameters are constant expressions.

But string literals are never constant expressions, which makes this
technique irrelevant.  So what good are they?
--
    --Andrew Koenig
      ark@research.att.com




Author: dan@snap.prds.cdx.mot.com (Dan Breslau)
Date: Tue, 14 Sep 1993 17:41:25 GMT
Raw View
ark@alice.att.com (Andrew Koenig) writes:

>Would someone mind explaining to me why having string literals as
>template parameters is useful?

>I see why it's useful to have integers: it allows things like this:

> template<class T, size_t size> class Buffer {
>  // ...
>  T buf[size];
>  // ...
> };

>which avoids the overhead of dynamically allocating buf separately.
>This works because `size' is a constant expression, which in turn works
>because integral template parameters are constant expressions.

>But string literals are never constant expressions, which makes this
>technique irrelevant.  So what good are they?
>--
>    --Andrew Koenig
>      ark@research.att.com


I developed a manifest-typing library, which includes persistence.  I
had originally designed it to use string literals for "tagging" the
stored types (being as I needed a tag value space which would last
across lifetimes of a process.)  I was going by Stroustrup's _The C++
Programming Language_, 2nd Edition, p. 279, which explicitly states
that character strings may be used as template arguments.

Finding out that this wasn't so didn't exactly make my day.
--
----------------------------------
Dan Breslau          dan@codex.com

Freude!




Author: ross@utopia.druid.com (Ross Ridge)
Date: Wed, 15 Sep 1993 01:26:02 GMT
Raw View
In article <26564@alice.att.com> ark@alice.UUCP () writes:
>Would someone mind explaining to me why having string literals as
>template parameters is useful?

To print out a more informative error or debugging message.

Eg:
 template<class T, size_t size, char const *MSG> class Buffer {
  // ...
  T buf[size];
  // ...
  T operator[](int index) {
   if (index < 0 || index >= size) {
    cerr << "Buffer<" << MSG
         << ", " << size << ">::operator[]:"
         "Index out of range.";
    abort();
   }
   return buf[index];
  }
  // ..
 };

 char const double_name[] = "double";
 char const string_name[] = "string";

 template<double, 10, double_name> foo;
 template<string, 5, string_name> bar;

Sure, in this case you can use a debugger to find out which template class
aborted, but having it print this bit of information itself can be
convienent.  On the other hand if your debugger doesn't demangle names
this turns out to be useful in more way than one.

       Ross Ridge


>
>which avoids the overhead of dynamically allocating buf separately.
>This works because `size' is a constant expression, which in turn works
>because integral template parameters are constant expressions.
>
>But string literals are never constant expressions, which makes this
>technique irrelevant.  So what good are they?
>--
>    --Andrew Koenig
>      ark@research.att.com






Author: pete@borland.com (Pete Becker)
Date: Wed, 15 Sep 1993 17:32:28 GMT
Raw View
In article <1993Sep15.012602.16824@utopia.druid.com>,
Ross Ridge <ross@utopia.druid.com> wrote:
>In article <26564@alice.att.com> ark@alice.UUCP () writes:
>>Would someone mind explaining to me why having string literals as
>>template parameters is useful?
>
>To print out a more informative error or debugging message.
>[example omitted]
>Sure, in this case you can use a debugger to find out which template class
>aborted, but having it print this bit of information itself can be
>convienent.  On the other hand if your debugger doesn't demangle names
>this turns out to be useful in more way than one.
>

 So far the two responses to Andy's question have both involved
displaying the name of a class. Since RTTI gives you this capability I don't
find these examples particularly helpful. I can do the same thing much more
directly:

 template <class T> void ShowError( const T& t )
 {
 cout << "Error in class " << typeid(t).name() << endl;
 }

 Does anybody have a different example?
 -- Pete




Author: dan@snap.prds.cdx.mot.com (Dan Breslau)
Date: Wed, 15 Sep 1993 22:11:00 GMT
Raw View
pete@borland.com (Pete Becker) writes:

>In article <1993Sep15.012602.16824@utopia.druid.com>,
>Ross Ridge <ross@utopia.druid.com> wrote:
>>In article <26564@alice.att.com> ark@alice.UUCP () writes:
>>>Would someone mind explaining to me why having string literals as
>>>template parameters is useful?
>>
>>To print out a more informative error or debugging message.
>>[example omitted]
>>Sure, in this case you can use a debugger to find out which template class
>>aborted, but having it print this bit of information itself can be
>>convienent.  On the other hand if your debugger doesn't demangle names
>>this turns out to be useful in more way than one.
>>

> So far the two responses to Andy's question have both involved
>displaying the name of a class. Since RTTI gives you this capability I don't
>find these examples particularly helpful. I can do the same thing much more
>directly:

> template <class T> void ShowError( const T& t )
> {
> cout << "Error in class " << typeid(t).name() << endl;
> }

> Does anybody have a different example?
> -- Pete

Our C++ implementation supports templates and even exceptions, but not
(so far as I can tell) RTTI.  Since I was writing about something I've
long since had to implement, it's RTTI I didn't find particularly
helpful.
--
----------------------------------
Dan Breslau          dan@codex.com

Freude!




Author: hendrik@vedge.com (Hendrik Boom)
Date: Wed, 15 Sep 1993 20:35:42 GMT
Raw View
rfg@netcom.com (Ronald F. Guilmette) writes:
: In article <KANZE.93Sep10121617@slsvhdt.us-es.sel.de> kanze@us-es.sel.de (James Kanze) writes:
:
: >Actually, I think the issue is less clear than I present it.  An array
: >only degenerates to a pointer in certain well defined contexts; is
: >template instantiation one of these?  Section 8.2.4 of the ARM states
: >that: "When an identifier of array type appears in an expression,
: >except as the operand of sizeof or & or used to initialize a
: >reference, it is converted into a pointer to the first member of the
: >array."  In the absence of any other specifications, I would interpret
: >this as saying yes, an array does degenerate into a pointer when used
: >for template instantiation.
:
: I would agree.  Note however that this point only implies that *if* string
: literals were allowed as template actual instantiation arguments, then
: such an argument would have to be matched by a corresponding template
: formal (non-type) parameter declared to have type `char*'.  (On this
: point I think everyone would agree.)

Not everyone.  I still prefer char[]. Presumably if string literals
were to be allowed as template actual instantiation arguments, you
would want the list of places where arrays are NOT turned into pointers to
include template actual instantiation arguments.  For one thing,
the string literal might be used inside the template as
the operand of sizeof or & or to initialize a reference
--
-------------------------------------------------------
Try one or more of the following addresses to reply.
at work: hendrik@vedge.com,  iros1!vedge!hendrik
at home: uunet!ozrout!topoi!hendrik




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Thu, 9 Sep 1993 10:43:04 GMT
Raw View
In article <1993Sep7.181317.6577@borland.com> pete@borland.com (Pete Becker) writes:
>In article <1993Sep4.092017.26113@frmug.fr.net>,
>Serge Weinstock <serguei@frmug.fr.net> wrote:
>>Hello,
>>
>>Is it possible to pass litteral string as template parameter
>>for the ATT translator v3.0 ?
>
> There's a fundamental problem with using literal strings as parameters
>to templates:
>
> template <const char *name> Foo { ... };
>
> Foo<"arg"> f1;
> Foo<"arg"> f2;
>
> Are f1 and f2 of the same type? Keeping in mind, of course, that the
>compiler can create two literals here or just one...

C'mon Pete.  Of course they are the same type!  Just as for:

 template <int arg> Foo { ... };

 Foo<99> f1;
 Foo<99> f2;

--

-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------




Author: aldrich@sequent.com (Jonathan Aldrich)
Date: Thu, 9 Sep 93 15:47:18 GMT
Raw View
In article <rfgCD31rs.7Eq@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>In article <1993Sep7.181317.6577@borland.com> pete@borland.com (Pete Becker) writes:
>>In article <1993Sep4.092017.26113@frmug.fr.net>,
>>Serge Weinstock <serguei@frmug.fr.net> wrote:
>>>Hello,
>>>
>>>Is it possible to pass litteral string as template parameter
>>>for the ATT translator v3.0 ?
>>
>>            There's a fundamental problem with using literal strings as
>>            parameters to templates:
>>
>>            template <const char *name> Foo { ... };
>>
>>            Foo<"arg"> f1;
>>            Foo<"arg"> f2;
>>
>>            Are f1 and f2 of the same type? Keeping in mind, of course,
>>            that the compiler can create two literals here or just
>>            one...
>C'mon Pete.  Of course they are the same type!  Just as for:
>
>              template <int arg> Foo { ... };
>
>              Foo<99> f1;
>              Foo<99> f2;

Not true!  The value of "arg" is its address, not the four letters
a-r-g-\0.  If you put two literals in your text that are the same
(like "arg" and "arg") the compiler may or may not put them at the
same address in the executable--in other words,

        Foo<"arg"> may REALLY be Foo<0x4AF62CE9> and
        Foo<"arg"> may REALLY be Foo<0x4B29D00F>!

where 0x4AF62CE9 and 0x4B29D00F are the locations in memory of the
two strings.

-Jonathan Aldrich




Author: kanze@us-es.sel.de (James Kanze)
Date: 9 Sep 93 19:43:53
Raw View
In article <rfgCD31rs.7Eq@netcom.com> rfg@netcom.com (Ronald F.
Guilmette) writes:

|> In article <1993Sep7.181317.6577@borland.com> pete@borland.com (Pete Becker) writes:
|> >In article <1993Sep4.092017.26113@frmug.fr.net>,
|> >Serge Weinstock <serguei@frmug.fr.net> wrote:
|> >>Hello,

|> >>Is it possible to pass litteral string as template parameter
|> >>for the ATT translator v3.0 ?

|> > There's a fundamental problem with using literal strings as parameters
|> >to templates:

|> > template <const char *name> Foo { ... };

|> > Foo<"arg"> f1;
|> > Foo<"arg"> f2;

|> > Are f1 and f2 of the same type? Keeping in mind, of course, that the
|> >compiler can create two literals here or just one...

|> C'mon Pete.  Of course they are the same type!  Just as for:

|>  template <int arg> Foo { ... };

|>  Foo<99> f1;
|>  Foo<99> f2;

Do you mean, "of course, they're the same type" literally.  Or were
you trying to say: "of course, they should (naturally) be the same
type."

My reading of the ARM (keeping in mind that a string literally is an
array, and that the value of an array, in most contexts, is its
address) agrees with Pete's interpretation.  Of course, that doesn't
prove that this is how it should be.  Or that this is an instinctive
and immediately obvious fact to a neophyte (or even an experienced)
programmer.
--
James Kanze                             email: kanze@us-es.sel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                   -- Beratung in industrieller Datenverarbeitung




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Fri, 10 Sep 1993 06:17:10 GMT
Raw View
In article <1993Sep9.154718.27250@sequent.com> aldrich@sequent.com (Jonathan Aldrich) writes:
>In article <rfgCD31rs.7Eq@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>>In article <1993Sep7.181317.6577@borland.com> pete@borland.com (Pete Becker) writes:
>>>In article <1993Sep4.092017.26113@frmug.fr.net>,
>>>Serge Weinstock <serguei@frmug.fr.net> wrote:
>>>>Hello,
>>>>
>>>>Is it possible to pass litteral string as template parameter
>>>>for the ATT translator v3.0 ?
>>>
>>>            There's a fundamental problem with using literal strings as
>>>            parameters to templates:
>>>
>>>            template <const char *name> Foo { ... };
>>>
>>>            Foo<"arg"> f1;
>>>            Foo<"arg"> f2;
>>>
>>>            Are f1 and f2 of the same type? Keeping in mind, of course,
>>>            that the compiler can create two literals here or just
>>>            one...
>>C'mon Pete.  Of course they are the same type!  Just as for:
>>
>>              template <int arg> Foo { ... };
>>
>>              Foo<99> f1;
>>              Foo<99> f2;
>
>Not true!  The value of "arg" is its address, not the four letters
>a-r-g-\0.  If you put two literals in your text that are the same
>(like "arg" and "arg") the compiler may or may not put them at the
>same address in the executable--in other words,

I fail to see how that fact has anything to do with anything.

You are trying to make some (obscure?) point about low-level implementation
details, and I'm talking about high-level (type) semantics.  The former
does not necessarily have a direct effect (let alone a controlling effect)
upon the latter.

--

-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Fri, 10 Sep 1993 06:29:22 GMT
Raw View
In article <KANZE.93Sep9194353@slsvhdt.us-es.sel.de> kanze@us-es.sel.de (James Kanze) writes:
>In article <rfgCD31rs.7Eq@netcom.com> rfg@netcom.com (Ronald F.
>Guilmette) writes:
>
>|> In article <1993Sep7.181317.6577@borland.com> pete@borland.com (Pete Becker) writes:
>|> >In article <1993Sep4.092017.26113@frmug.fr.net>,
>|> >Serge Weinstock <serguei@frmug.fr.net> wrote:
>|> >>Hello,
>
>|> >>Is it possible to pass litteral string as template parameter
>|> >>for the ATT translator v3.0 ?
>
>|> > There's a fundamental problem with using literal strings as parameters
>|> >to templates:
>
>|> > template <const char *name> Foo { ... };
>
>|> > Foo<"arg"> f1;
>|> > Foo<"arg"> f2;
>
>|> > Are f1 and f2 of the same type? Keeping in mind, of course, that the
>|> >compiler can create two literals here or just one...
>
>|> C'mon Pete.  Of course they are the same type!  Just as for:
>
>|>  template <int arg> Foo { ... };
>
>|>  Foo<99> f1;
>|>  Foo<99> f2;
>
>Do you mean, "of course, they're the same type" literally.  Or were
>you trying to say: "of course, they should (naturally) be the same
>type."

Yes.  The latter.

>My reading of the ARM (keeping in mind that a string literally is an
>array, and that the value of an array, in most contexts, is its
>address) agrees with Pete's interpretation.

I don't remember anymore if Pete even gave us his interpretation regarding
the question of the sameness of the types.  I rather doubt that he even
bothered because (being the good implementor he is) I'm sure that he is
aware that (as of this time) it isn't even ALLOWED to supply string literals
as template actual instantiation arguments.  Thus, for the moment at least,
the type of `Foo<"arg">' isn't even something worth talking about, as that
is simply an illegal instantiation.

(My point was that if this *were* to be allowed, sometime in the future,
then I, for one, would want the type rules to be such that `Foo<"arg">'
meant the same thing wherever you wrote it.  I don't believe that any
other choice would be reasonable.)

--

-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------




Author: kanze@us-es.sel.de (James Kanze)
Date: 10 Sep 93 12:16:17
Raw View
In article <rfgCD4K4n.IL5@netcom.com> rfg@netcom.com (Ronald F.
Guilmette) writes:

|> You are trying to make some (obscure?) point about low-level implementation
|> details, and I'm talking about high-level (type) semantics.  The former
|> does not necessarily have a direct effect (let alone a controlling effect)
|> upon the latter.

Again, if you say: "the former *shouldn't* ...", I would agree.  But
this is C++, derived from C, and the low level implementation details
of an array (and thus of a string literal) do have an effect on type
semantics.  Of course, since the question involves templates, there is
no C compatibility issue, and the standards committee could bless what
you want.  But I don't think they have yet.  (String literals already
behave differently than other arrays when used to initialize a char
array, so there would be nothing to prevent similar rules from being
used when instantiating templates.)

Actually, I think the issue is less clear than I present it.  An array
only degenerates to a pointer in certain well defined contexts; is
template instantiation one of these?  Section 8.2.4 of the ARM states
that: "When an identifier of array type appears in an expression,
except as the operand of sizeof or & or used to initialize a
reference, it is converted into a pointer to the first member of the
array."  In the absence of any other specifications, I would interpret
this as saying yes, an array does degenerate into a pointer when used
for template instantiation.
--
James Kanze                             email: kanze@us-es.sel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                   -- Beratung in industrieller Datenverarbeitung




Author: bruce@liverpool.ac.uk (Bruce Stephens)
Date: Fri, 10 Sep 1993 10:47:27 GMT
Raw View
>>>>> On Fri, 10 Sep 1993 06:17:10 GMT, rfg@netcom.com (Ronald F. Guilmette) said:

> In article <1993Sep9.154718.27250@sequent.com> aldrich@sequent.com (Jonathan Aldrich) writes:

>>Not true!  The value of "arg" is its address, not the four letters
>>a-r-g-\0.  If you put two literals in your text that are the same
>>(like "arg" and "arg") the compiler may or may not put them at the
>>same address in the executable--in other words,

> I fail to see how that fact has anything to do with anything.

Seems quite simple to me.  "arg" != "arg" in some implementations, and
in general it is not guaranteed that "arg"=="arg".

I agree it makes sense to make character constants a special case for
templates (and compare in the !strcmp sense), but they *are* a special
case.

> --

> -- Ronald F. Guilmette ------------------------------------------------------
> ------ domain address: rfg@netcom.com ---------------------------------------
> ------ uucp address: ...!uunet!netcom.com!rfg -------------------------------
--
Bruce                    Institute of Advanced Scientific Computing
bruce@liverpool.ac.uk    University of Liverpool




Author: pete@borland.com (Pete Becker)
Date: Fri, 10 Sep 1993 17:25:45 GMT
Raw View
In article <rfgCD4Koy.JLz@netcom.com>,
Ronald F. Guilmette <rfg@netcom.com> wrote:
>
>I don't remember anymore if Pete even gave us his interpretation regarding
>the question of the sameness of the types.

 I didn't. I'd rather watch the discussion develop.

>
>(My point was that if this *were* to be allowed, sometime in the future,
>then I, for one, would want the type rules to be such that `Foo<"arg">'
>meant the same thing wherever you wrote it.  I don't believe that any
>other choice would be reasonable.)
>

 What about these two? Is there a simple rule that's reasonably
intuitive to C programmers moving to C++?

 template <const char *name> class Foo;

 Foo<"arg"> f1;

 const char *cp = "arg";
 Foo<cp> f2;

Of course, the next one is this:

 const char *cp1;
 Foo<cp1> f3;

The problem isn't so much in coming up with a rule that works for literals
(ignoring for the moment the question of whether to restrict literals that
are used as template parameters to the source character set), but of making
the usage reasonably consistent with the usage of literal strings in general.
 -- Pete




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Fri, 10 Sep 1993 17:11:04 GMT
Raw View
In article <KANZE.93Sep10121617@slsvhdt.us-es.sel.de> kanze@us-es.sel.de (James Kanze) writes:
>In article <rfgCD4K4n.IL5@netcom.com> rfg@netcom.com (Ronald F.
>Guilmette) writes:
>
>|> You are trying to make some (obscure?) point about low-level implementation
>|> details, and I'm talking about high-level (type) semantics.  The former
>|> does not necessarily have a direct effect (let alone a controlling effect)
>|> upon the latter.
>
>Again, if you say: "the former *shouldn't* ...", I would agree.  But
>this is C++, derived from C, and the low level implementation details
>of an array (and thus of a string literal) do have an effect on type
>semantics.  Of course, since the question involves templates, there is
>no C compatibility issue, and the standards committee could bless what
>you want.  But I don't think they have yet.

Yes.  Sad but true.

>Actually, I think the issue is less clear than I present it.  An array
>only degenerates to a pointer in certain well defined contexts; is
>template instantiation one of these?  Section 8.2.4 of the ARM states
>that: "When an identifier of array type appears in an expression,
>except as the operand of sizeof or & or used to initialize a
>reference, it is converted into a pointer to the first member of the
>array."  In the absence of any other specifications, I would interpret
>this as saying yes, an array does degenerate into a pointer when used
>for template instantiation.

I would agree.  Note however that this point only implies that *if* string
literals were allowed as template actual instantiation arguments, then
such an argument would have to be matched by a corresponding template
formal (non-type) parameter declared to have type `char*'.  (On this
point I think everyone would agree.)

The *real* questions (i.e. those on which there may be less than universal
agreement) are:

 o   Why doesn't the ARM (or the current X3J16 working paper) permit
     string literals to be used as template actual instantiation
     arguments?

 o   Should this (unnecessary?) restriction be lifted?

 o   If it *were* lifted, then would a "type name" such as foo<"bar">
     designate the same single type even if it were written in several
     different places in a given translation unit?

 o   If the restriction *were* lifted, then would a "type name" such
     as foo<"bar"> designate the same single type even if it were
     written in several different places in several of the translation
     units of a given program?

--

-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Sat, 11 Sep 1993 17:31:41 GMT
Raw View
In article <1993Sep10.172545.27437@borland.com> pete@borland.com (Pete Becker) writes:
>In article <rfgCD4Koy.JLz@netcom.com>,
>Ronald F. Guilmette <rfg@netcom.com> wrote:
>>
>>I don't remember anymore if Pete even gave us his interpretation regarding
>>the question of the sameness of the types.
>
> I didn't. I'd rather watch the discussion develop.

A wise choice.

>>(My point was that if this *were* to be allowed, sometime in the future,
>>then I, for one, would want the type rules to be such that `Foo<"arg">'
>>meant the same thing wherever you wrote it.  I don't believe that any
>>other choice would be reasonable.)
>>
>
> What about these two? Is there a simple rule that's reasonably
>intuitive to C programmers moving to C++?
>
> template <const char *name> class Foo;
>
> Foo<"arg"> f1;
>
> const char *cp = "arg";
> Foo<cp> f2;

Pete, your example of `Foo<cp>' is *definitely* illegal (and would, I
would hope, continue to be illegal even if the rules were changed to
permit string literals as template instantiation actuals).

The ARM (in 14.2c on page 343) says:

 "Other template-args must be (a) constant-expressions, or (b)
 addresses of external-linkage objects, functions, or class
 members."

(OK.  It doesn't *quite* say that.  I have taken the liberty of cleaning
up the wording of this rule slightly so that an English speaker can parse
the rule properly and unambiguously.)

In your example Pete, you used `cp' as a template instantiation actual
argument, but that is neither a constant expression, nor is it the
address of some entity which has external linkage.  So `Foo<cp>' would
have to be diagnosed as erroneous.

>Of course, the next one is this:
>
> const char *cp1;
> Foo<cp1> f3;

Same thing again.  This is also illegal.

>The problem isn't so much in coming up with a rule that works for literals
>(ignoring for the moment the question of whether to restrict literals that
>are used as template parameters to the source character set), but of making
>the usage reasonably consistent with the usage of literal strings in general.

I agree, but I have yet to see any insurmountable problem(s).

--

-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------




Author: mat@mole-end.matawan.nj.us
Date: Sat, 11 Sep 1993 17:20:05 GMT
Raw View
In article <rfgCD5EEH.JBE@netcom.com>, rfg@netcom.com (Ronald F. Guilmette) writes:
> In article <KANZE.93Sep10121617@slsvhdt.us-es.sel.de> kanze@us-es.sel.de (James Kanze) writes:
> >In article <rfgCD4K4n.IL5@netcom.com> rfg@netcom.com (Ronald F.
> >Guilmette) writes:

> The *real* questions (i.e. those on which there may be less than universal
> agreement) are:
>
>  o   Why doesn't the ARM (or the current X3J16 working paper) permit
>      string literals to be used as template actual instantiation
>      arguments?
>
>  o   Should this (unnecessary?) restriction be lifted?

Lifting it requires changes to the semantics of literals in a way that
most linkers cannot support.

>  o   If it *were* lifted, then would a "type name" such as foo<"bar">
>      designate the same single type even if it were written in several
>      different places in a given translation unit?

Without those semantic changes, it would not.  And since it would not, the
type name would be of limited use.

>  o   If the restriction *were* lifted, then would a "type name" such
>      as foo<"bar"> designate the same single type even if it were
>      written in several different places in several of the translation
>      units of a given program?

Ditto.
--
 (This man's opinions are his own.)
 From mole-end    Mark Terribile

 mat@mole-end.matawan.nj.us, Somewhere in Matawan, NJ




Author: fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON)
Date: Mon, 13 Sep 1993 03:06:28 GMT
Raw View
rfg@netcom.com (Ronald F. Guilmette) writes:

>pete@borland.com (Pete Becker) writes:
>> There's a fundamental problem with using literal strings as parameters
>>to templates:
>>
>> template <const char *name> Foo { ... };
>>
>> Foo<"arg"> f1;
>> Foo<"arg"> f2;
>>
>> Are f1 and f2 of the same type? Keeping in mind, of course, that the
>>compiler can create two literals here or just one...
>
>C'mon Pete.  Of course they are the same type!  Just as for:
>
> template <int arg> Foo { ... };
>
> Foo<99> f1;
> Foo<99> f2;

C'mon Ron, be realistic!  There is a big difference.
The difference is the same difference between
 assert("arg" == "arg");
and
 assert(99 == 99);
i.e. the former assertion may fail, whereas the latter is guaranteed to
succeed.

--
Fergus Henderson                     fjh@munta.cs.mu.OZ.AU




Author: fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON)
Date: Mon, 13 Sep 1993 03:13:19 GMT
Raw View
pete@borland.com (Pete Becker) writes:

>In article <rfgCD4Koy.JLz@netcom.com>,
>Ronald F. Guilmette <rfg@netcom.com> wrote:
>>
>>I don't remember anymore if Pete even gave us his interpretation regarding
>>the question of the sameness of the types.
>
> I didn't. I'd rather watch the discussion develop.
>
>>
>>(My point was that if this *were* to be allowed, sometime in the future,
>>then I, for one, would want the type rules to be such that `Foo<"arg">'
>>meant the same thing wherever you wrote it.  I don't believe that any
>>other choice would be reasonable.)
>>
>
> What about these two? Is there a simple rule that's reasonably
>intuitive to C programmers moving to C++?
>
> template <const char *name> class Foo;
>
> Foo<"arg"> f1;
>
> const char *cp = "arg";
> Foo<cp> f2;

This one is illegal, surely, because `cp' is not a compile-time constant
expression.  You would need to write

 const char * const cp = "arg";
       ^^^^^
 Foo<cp> f2;

instead, I believe.

>Of course, the next one is this:
>
> const char *cp1;
> Foo<cp1> f3;

This one has the same problem as the previous one, although it can't
be rectified except by providing an initializer.

--
Fergus Henderson                     fjh@munta.cs.mu.OZ.AU




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Mon, 13 Sep 1993 07:01:36 GMT
Raw View
In article <1993Sep11.172005.25534@mole-end.matawan.nj.us> mat@mole-end.matawan.nj.us writes:
>In article <rfgCD5EEH.JBE@netcom.com>, rfg@netcom.com (Ronald F. Guilmette) writes:
>> In article <KANZE.93Sep10121617@slsvhdt.us-es.sel.de> kanze@us-es.sel.de (James Kanze) writes:
>> >In article <rfgCD4K4n.IL5@netcom.com> rfg@netcom.com (Ronald F.
>> >Guilmette) writes:
>
>> The *real* questions (i.e. those on which there may be less than universal
>> agreement) are:
>>
>>  o   Why doesn't the ARM (or the current X3J16 working paper) permit
>>      string literals to be used as template actual instantiation
>>      arguments?
>>
>>  o   Should this (unnecessary?) restriction be lifted?
>
>Lifting it requires changes to the semantics of literals in a way that
>most linkers cannot support.

I do not buy that argument at all.

In a separate message I suggested that the actual characters which make
up the *value* of each string literal (as opposed to the *address* of
that literal) could be "mangled-in" as part of the mangled names of
template instances.

I believe that such an approach is obvious, workable, and trivially easy
to implement, and that it *would* permit implementations to support
string literals as template actual instantiation parameters... even
for those implementations which obtain only the most meager support
from the underlying system linker.

--

-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------




Author: serguei@frmug.fr.net (Serge Weinstock)
Date: Sat, 4 Sep 1993 09:20:17 GMT
Raw View
Hello,

Is it possible to pass litteral string as template parameter
for the ATT translator v3.0 ? What I would like to do is
something like that :

template <class type,const char *typeName>
class Test {
    .....
};

Test<double,"double"> tdb;
Test<string,"string"> ts;

in order to be able to make the distinction between Test<double>
and Test<string>. The ATT translator v3.0 says that this feature
is not yet implemented. Does anoyone has an idea on how to solve
this problem or at least to have a way to make the distinction
between class with parameter types?...


Thank you


--
******************************************************
   Serge Weinstock    (serguei@frmug.fr.mugnet.org)

Res du Parc, Bat F




Author: serguei@frmug.fr.net (Serge Weinstock)
Date: Sat, 4 Sep 1993 09:24:12 GMT
Raw View
Hello,

Is it possible to pass litteral string as template parameter
for the ATT translator v3.0 ? What I would like to do is
something like that :

template <class type,const char *typeName>
class Test {
    .....
};

Test<double,"double"> tdb;
Test<string,"string"> ts;

in order to be able to make the distinction between Test<double>
and Test<string>. The ATT translator v3.0 says that this feature
is not yet implemented. Does anoyone has an idea on how to solve
this problem or at least to have a way to make the distinction
between class with parameter types?...


Thank you


--
******************************************************
   Serge Weinstock    (serguei@frmug.fr.mugnet.org)

Res du Parc, Bat F




Author: grahamd@swdev.research.otc.com.au (Graham Dumpleton)
Date: 6 Sep 1993 02:49:37 GMT
Raw View
In article <1993Sep4.092017.26113@frmug.fr.net>, serguei@frmug.fr.net (Serge Weinstock) writes:
 > Hello,
 >
 > Is it possible to pass litteral string as template parameter
 > for the ATT translator v3.0 ? What I would like to do is
 > something like that :
 >
 > template <class type,const char *typeName>
 > class Test {
 >     .....
 > };
 >
 > Test<double,"double"> tdb;
 > Test<string,"string"> ts;
 >
 > in order to be able to make the distinction between Test<double>
 > and Test<string>. The ATT translator v3.0 says that this feature
 > is not yet implemented. Does anoyone has an idea on how to solve
 > this problem or at least to have a way to make the distinction
 > between class with parameter types?...

How about using template override classes.

The idea is to start with a default template class (with no implementation)
as follows:

  template<class T>
  class ClassName
  {
    public:
      static char const* name();
  };

Your template class, instead of taking two arguments, would just take one,
that of the type:

  template <class T>
  class Test
  {
  };

In the implementation of your template class, where you need the string
name of the class, use:

  char const* name = ClassName<T>::name();

Now, for each of the classes which you know will be used as argument to
your template, define an implementation for ClassName<T>::name(). For
example:

  char const* ClassName<double>::name()
  {
    return "double";
  }

  char const* ClassName<string>::name()
  {
    return "string";
  }

You could quite easily create a little script which when fed the names of a
whole lot of types, could generate the ClassName<T>::name() implementations
automatically.

We use a scheme like this to make the job of generating os_typespec classes
when using the ObjectStore OODBMS easier. Not too much effort and avoids
the alternative which is to add static member functions to the type, which
for builtin types and pointers obviously cannot be done.

--
Graham Dumpleton (grahamd@swdev.research.otc.com.au)




Author: mat@mole-end.matawan.nj.us
Date: Mon, 6 Sep 1993 09:12:07 GMT
Raw View
In article <26e8g1$j2e@turin.research.otc.com.au>, grahamd@swdev.research.otc.com.au (Graham Dumpleton) writes:
> In article <1993Sep4.092017.26113@frmug.fr.net>, serguei@frmug.fr.net (Serge Weinstock) writes:
>  > Hello,
>  >
>  > Is it possible to pass litteral string as template parameter
>  > for the ATT translator v3.0 ? What I would like to do is
>  > something like that :
>  >
>  > template <class type,const char *typeName>
>  > class Test {
>  >     .....
>  > };
>  >
>  > Test<double,"double"> tdb;
>  > Test<string,"string"> ts;
>  >
>  > in order to be able to make the distinction between Test<double>
>  > and Test<string>. The ATT translator v3.0 says that this feature
>  > is not yet implemented. Does anoyone has an idea on how to solve
>  > this problem or at least to have a way to make the distinction
>  > between class with parameter types?...

You can't do it with strings as template parameters, and for good reason.

If you were to write

 Templ_T< int, "int" >

twice, whether in two different files or twice in the same file there is
NO guarantee whatsoever that the two instances of  "int"  will lie at
the same address, and since the address of a literal is also its value,
there's no way _ever_ to ensure that the two type names generated by
specializing the templates are the same.

Generally, a value parameter (such as a string literal) that is not used
to declare the size of something should be a parameter to the constructor,
not a template parameter.

(My _Practical C++_ covers this explicitly, BTW.)

You have an interesting case, though.

One way to test for equality-of-specialization is to compare the address
of a static variable specialized from the template.

> How about using template override classes.
>
> The idea is to start with a default template class ...
>
>   char const* ClassName<double>::name()
>   {
>     return "double";
>   }

This sounds like (ugh!) a good use for the preprocessor:

#define STRINGIZE( X ) #X

 .. .. .. ..

#define ID_Func( T ) \
 char const* \
 ClassName< T >::name() const \
 { \
  return STRINGIZE( T ) ; \
 }

 .. .. .. ..

class ClassName< int > ;
class ClassName< double > ;
class ClassName< char const* > ;

 .. .. .. ..

ID_func( int )
ID_func( double )
ID_func( char const* )

 .. .. .. ..
--
 (This man's opinions are his own.)
 From mole-end    Mark Terribile

 mat@mole-end.matawan.nj.us, Somewhere in Matawan, NJ




Author: pete@borland.com (Pete Becker)
Date: Tue, 7 Sep 1993 18:13:17 GMT
Raw View
In article <1993Sep4.092017.26113@frmug.fr.net>,
Serge Weinstock <serguei@frmug.fr.net> wrote:
>Hello,
>
>Is it possible to pass litteral string as template parameter
>for the ATT translator v3.0 ?

 There's a fundamental problem with using literal strings as parameters
to templates:

 template <const char *name> Foo { ... };

 Foo<"arg"> f1;
 Foo<"arg"> f2;

 Are f1 and f2 of the same type? Keeping in mind, of course, that the
compiler can create two literals here or just one...
 In order to avoid confusion and portability problems, it's probably
better to use an explicit string array:

 const char *ArgName = "arg";
 Foo<ArgName> f1;
 Foo<ArgName> f2;

 -- Pete




Author: grahamd@swdev.research.otc.com.au (Graham Dumpleton)
Date: 9 Sep 1993 01:57:03 GMT
Raw View
 > > How about using template override classes.
 > >
 > > The idea is to start with a default template class ...
 > >
 > >   char const* ClassName<double>::name()
 > >   {
 > >     return "double";
 > >   }
 >
 > This sounds like (ugh!) a good use for the preprocessor:
 >
 > #define STRINGIZE( X ) #X
 >
 >  .. .. .. ..
 >
 > #define ID_Func( T ) \
 >  char const* \
 >  ClassName< T >::name() const \
 >  { \
 >   return STRINGIZE( T ) ; \
 >  }
 >
 >  .. .. .. ..
 >
 > class ClassName< int > ;
 > class ClassName< double > ;
 > class ClassName< char const* > ;
 >
 >  .. .. .. ..
 >
 > ID_func( int )
 > ID_func( double )
 > ID_func( char const* )

Whether a preprocessor macro is adequate will depend on whether there are
strict rules as to the format of the string return by the name() function.
As an example, in ObjectStore, they expect all "const" information to be
thrown out. This is because when it comes down to the type schemas in the
database, the constness doesn't matter. Therefore you would have:

  char const* ClassName<double*>::name()
  {
    return "double*";
  }

  char const* ClassName<double const*>::name()
  {
    return "double*";
  }

Admittedly this is a special case, however, even in what you have there is
room for ambiguity and problems. For example the following would produce
the same template type, but the string would be different.

  ID_func( double const* )
  ID_func( const double* )

Therefore, software which may be interpreting the strings would have to
flexible to cope with "const" being in different locations.

A further example is where the type is a template taking multiple arguments.
In this case you cannot write:

  ID_func( Map<int,double> )

as the preprocessor will interpret the "," as being an argument separator
for the macro. Therefore you have to write it as:

  ID_func( (Map<int,double>) )

but then you have brackets appearing in your string.

It is for these reasons that I suggested some tool which generates the
function implementations from a list of classes in a file be used, as it
can be made just that little bit more intelligent than what preprocessor
macros are.

--
Graham Dumpleton (grahamd@swdev.research.otc.com.au)




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Thu, 9 Sep 1993 10:35:54 GMT
Raw View
In article <1993Sep6.091207.7390@mole-end.matawan.nj.us> mat@mole-end.matawan.nj.us writes:
>In article <26e8g1$j2e@turin.research.otc.com.au>, grahamd@swdev.research.otc.com.au (Graham Dumpleton) writes:
>> In article <1993Sep4.092017.26113@frmug.fr.net>, serguei@frmug.fr.net (Serge Weinstock) writes:
>>  > Hello,
>>  >
>>  > Is it possible to pass litteral string as template parameter?
...
>You can't do it with strings as template parameters, and for good reason.
>
>If you were to write
>
> Templ_T< int, "int" >
>
>twice, whether in two different files or twice in the same file there is
>NO guarantee whatsoever that the two instances of  "int"  will lie at
>the same address, and since the address of a literal is also its value,
>there's no way _ever_ to ensure that the two type names generated by
>specializing the templates are the same.
>
>Generally, a value parameter (such as a string literal) that is not used
>to declare the size of something should be a parameter to the constructor,
>not a template parameter.
>
>(My _Practical C++_ covers this explicitly, BTW.)

I trust that it covers it better that you have here!

Above, you seemed to be making some claim that there was some good *implemen-
tation* related reason why string literals could not be used as template
actual non-type instantiation arguments.

All I can say is that I found your "argument" (if I could call it that)
somewhat less that convincing.

It is quite apparent that implementations *can* and implementations *do*
permit actual template arguments corresponding to template non-type formal
arguments to be constants (as allowed by the rule at the very bottom of
page 343 of the ARM) and so given the fact that a string literal (such
as "hello") decays into a pointer constant, I don't really see why anyone
would claim that it would be harder for implementations to support this
kind of constant (as a template actual) than it would be for implementations
to support other kinds of constants.

OK.  I understand that for the sake of current name-mangling-based linkage
schemes you would like to have the *address* of the literal "hello" be
the same with respect to all of the compilation units in which this
literal is used as a template instantiation argument.  I also understand
that current linker technology doesn't give us that capability, but surely
using the *addresses* of the string literals isn't the *only* possible way
to get the names of otherwise identical instantiations (involving string
literal actual template arguments) to "mangle up" the same in two (or more)
different translation units!  Why not just take the value of the characters
of the string literal themselves and somehow mangle those in as part of the
process of creating the mangled names for the various template instances?
I believe that would work.  Then we *could* use string literals as template
actuals!

--

-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------