Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss
Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

template <char* T> class?

0 views
Skip to first unread message

Alex Vinokur

unread,
Feb 3, 1999, 3:00:00 AM2/3/99
to

Hi,

I need the following template class.

//####################################
#include <string>

//=========================
template <char* T>
class AAA
{
public :
AAA () {cout << "Constructor : " << T << endl;}
~AAA () {}

};

//=========================
int main ()
{
AAA<"xyz"> aaa;

//===========
return 0;
}
//####################################


But I have the following error message :

object `"xyz"' cannot be used as template argument
warning: ANSI C++ forbids declaration `aaa' with no type

//####################################

g++ -v : gcc version egcs-2.91.57 19980901 (egcs-1.1 release)

//####################################

Can we create template classes :
template <char* T>
template <char[] T>
template <string S>
?

We can create template function with these template.
But what about template classes?

//####################################

Thanks in advance
Alex


-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own


[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]

Paul Lutus

unread,
Feb 3, 1999, 3:00:00 AM2/3/99
to
I believe you are misinterpreting the meaning of templates. Try this example
instead:

#include <iostream>

template <class T>

class AAA
{
public :
AAA (T initValue) {
cout << "Constructor : " << initValue << endl;
}
};

int main()
{

AAA<char *> a("this");
AAA<double> b(80.0/81.0);

return 0;
}

Paul Lutus

Alex Vinokur wrote in message <796r0t$to9$1...@nnrp1.dejanews.com>...
>
>
>Hi,


<snip>

Alex Vinokur

unread,
Feb 4, 1999, 3:00:00 AM2/4/99
to
In article <79a8l6$7up$1...@remarQ.com>,


===============================
Siemel Naran wrote :

In article <slrn7be93u....@localhost.localdomain>,
sbn...@uiuc.edu wrote:
> On Tue, 02 Feb 1999 12:27:34 GMT, Alex Vinokur


>
> >template <char* T>
> >class AAA
>

> >int main ()
> >{
> >AAA<"xyz"> aaa;
> >}
>

> The problem is that the literal "xyz" has internal linkage. That
> is, only main() can see "xyz". In general, the class AAA<char*>
> will be instantiated at link time. At this point, the linker
> needs to see the definition of the literal. Yet it can't because
> the literal has internal linkage. Therefore, this works:
> char text[]="xyz";
> int main() { AAA<text> aaa; }
>
> The following does not work
> extern char *const text="abc";
> int main() { AAA<text> aaa; }
> The standard discusses this in 14.3.2 "Template non-type arguments",
> item 2. The literal itself has internal linkage.
>
> Perhaps you want the text to be const. Then,
> template <const char * text> class AAA { };
> extern char text[]="xyz";
> int main() { AAA<text> aaa; }
>
> --
> ----------------------------------
> Siemel B. Naran (sbn...@uiuc.edu)
> ----------------------------------
>


===============================
Dennis Handly wrote :

[snip]

> You need to use:
> char foo[] = __FILE__;
> template <char T[] = foo>
>
> Or possibly:
> #define concat(x,y) x ## y
> char concat(foo, __FILE__)[] = __FILE__;
> template <char T[] = concat(foo,__FILE__)>

[snip]


===============================
Here is an example.
Alex

//############ main ##############
#include <string>

//=========================
char text1[] = "First";
//=========================

//#########################
template <const char* T = text1>


class AAA
{
public :
AAA ()
{
cout << "Constructor : "

<< __PRETTY_FUNCTION__
<< " ---> "
<< T
<< endl;
}
~AAA () {}

};

//=========================
char text2 [] = "Second";
//=========================

//#########################
int main ()
{
AAA<> aaa1;
AAA<text2> aaa2;
strcpy (text2, "Third");
AAA<text2> aaa3;

//===========
return 0;
}

//############ Results ##############

Constructor : AAA<&text1>::AAA<(&text1)>() ---> First
Constructor : AAA<&text2>::AAA<(&text2)>() ---> Second
Constructor : AAA<&text2>::AAA<(&text2)>() ---> Third

//###################################

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own

Shiva

unread,
Feb 4, 1999, 3:00:00 AM2/4/99
to
Paul Lutus wrote:
>
> I believe you are misinterpreting the meaning of templates. Try this example

No he isn't.
There are three forms of template苔rgument, corresponding to the three
forms of template計arameter:
type,non負ype and template.

He is talking about the 2nd one, & you are talking about the first
one. Check out bitset in the STL.

And his problem is that a string literal is not an acceptable
template苔rgument because a string
literal is an object
with internal linkage.

> instead:
>
> #include <iostream>
>
> template <class T>
>
> class AAA
> {
> public :
> AAA (T initValue) {
> cout << "Constructor : " << initValue << endl;
> }
> };
>
> int main()
> {
>
> AAA<char *> a("this");
> AAA<double> b(80.0/81.0);
>
> return 0;
> }
>
> Paul Lutus
>


--
cheers,
Shiva
comp.lang.c++ FAQ: http://www.cerfnet.com/~mpcline/c++-faq-lite/
http://members.xoom.com/jshiva/

Siemel Naran

unread,
Feb 4, 1999, 3:00:00 AM2/4/99
to
On 3 Feb 1999 23:03:11 -0500, Paul Lutus <nos...@nosite.com> wrote:

>I believe you are misinterpreting the meaning of templates. Try this example

>instead:

No, the syntax
template <const char text[]> class X { };
is indeed allowed. The only restriction is that 'text' be an object
with external linkage. Eg,
extern const char text[]="Hello World";
int main() { X<text> x; }
See the thread on comp.lang.c++ for more details.

--
----------------------------------
Siemel B. Naran (sbn...@uiuc.edu)
----------------------------------

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Andrei Alexandrescu

unread,
Feb 5, 1999, 3:00:00 AM2/5/99
to
Alex Vinokur wrote in message <796r0t$to9$1...@nnrp1.dejanews.com>...
[snip]

The problem is that string literals have static linkage, and non-type
template parameters have to have external linkage. I would like to have a
handy way to say:

A<__FILE__> something;

but unfortunatley it doesn't work. What does work is:

extern const char * const ThisFile = __FILE__;
...
A<ThisFile> something;

but you cannot propagate the declaration in multiple files (link-time
clashes), so you're in a catch-22 situation :o).

Andrei

Thiemo Seufer

unread,
Feb 5, 1999, 3:00:00 AM2/5/99
to
Alex Vinokur wrote in message <79bp9c$4fb$1...@nnrp1.dejanews.com>...
[older replies snipped]

>Here is an example.
> Alex

>
>//############ main ##############
>#include <string>

unnecessary, needed instead:
#include <iostream>
using std::cout;
using std::endl;

>//=========================
>char text1[] = "First";
>//=========================
>
>//#########################
>template <const char* T = text1>

AFAIK, default template arguments are not allowed by the standard.
This is possibly a defect of C++.

>class AAA
>{
> public :
> AAA ()
> {
> cout << "Constructor : "
> << __PRETTY_FUNCTION__

undefined identifier "__PRETTY_FUNCTION__"
(compiler's extension ?)

> << " ---> "
> << T
> << endl;
> }
> ~AAA () {}
>
>};
>
>//=========================
>char text2 [] = "Second";
>//=========================
>
>//#########################
>int main ()
>{
>AAA<> aaa1;
>AAA<text2> aaa2;
> strcpy (text2, "Third");

Attempt to overwrite constant literal.

>AAA<text2> aaa3;
The type for second and third is the same.

> //===========
> return 0;
>}


As earlier mentioned in this thread, these template
arguments need extern storage class.

Thiemo Seufer

Adam P. Jenkins

unread,
Feb 6, 1999, 3:00:00 AM2/6/99
to
"Andrei Alexandrescu" <alexan...@micromodeling.com> writes:
> Alex Vinokur wrote in message <796r0t$to9$1...@nnrp1.dejanews.com>...
> [snip]
>
> The problem is that string literals have static linkage, and non-type
> template parameters have to have external linkage. I would like to
have a
> handy way to say:
>
> A<__FILE__> something;
>
> but unfortunatley it doesn't work. What does work is:
>
> extern const char * const ThisFile = __FILE__;
> ...
> A<ThisFile> something;
>
> but you cannot propagate the declaration in multiple files (link-time
> clashes), so you're in a catch-22 situation :o).

I thought I remember someone on here saying that a difference between
static file-level variables and variables in an anonymous namespace is
that the variables in the anonymous namespace have external linkage,
and can thus be used as template arguments. Is this true?

That would allow

namespace {


extern const char * const ThisFile = __FILE__;
}

and ThisFile would be a valid template argument for

template <const char* Name> class SomeClass {};

--
Adam P. Jenkins
ajen...@netway.com

Siemel Naran

unread,
Feb 6, 1999, 3:00:00 AM2/6/99
to
On 6 Feb 1999 15:31:17 -0500, Adam P. Jenkins <ajen...@netway.com> wrote:

>namespace {
>extern const char * const ThisFile = __FILE__;
>}

Yes, the pointer itself has external linkage. But the stuff the
pointer points to -- namely the string "myfile.c" -- still has
internal linkage. One must do this,

namespace {
extern const char ThisFile[] = __FILE__;
}

--
----------------------------------
Siemel B. Naran (sbn...@uiuc.edu)
----------------------------------

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Francis Glassborow

unread,
Feb 6, 1999, 3:00:00 AM2/6/99
to
In article <36b9f...@10.1.1.65>, Andrei Alexandrescu <alexandrescua@mi
cromodeling.com> writes

>The problem is that string literals have static linkage, and non-type
>template parameters have to have external linkage. I would like to have a
>handy way to say:
>
>A<__FILE__> something;
>
>but unfortunatley it doesn't work. What does work is:
>
>extern const char * const ThisFile = __FILE__;

What about dropping the extern, and placing the declaration in an
unnamed namespace

>...
>A<ThisFile> something;
>
>but you cannot propagate the declaration in multiple files (link-time
>clashes), so you're in a catch-22 situation :o).

Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

Siemel Naran

unread,
Feb 7, 1999, 3:00:00 AM2/7/99
to
On 6 Feb 1999 18:36:39 -0500, Francis Glassborow

>In article <36b9f...@10.1.1.65>, Andrei Alexandrescu
<alexandrescua@mi

>>extern const char * const ThisFile = __FILE__;


>
>What about dropping the extern, and placing the declaration in an
>unnamed namespace

'const' objects have internal linkage. So the 'extern' is necessary.
And yes, it should also be in an unnamed namespace.

--
----------------------------------
Siemel B. Naran (sbn...@uiuc.edu)
----------------------------------

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Alex Vinokur

unread,
Feb 7, 1999, 3:00:00 AM2/7/99
to
In article <79d3m4$h9q$1...@infosun2.rus.uni-stuttgart.de>,
"Thiemo Seufer" <seu...@csv.ica.uni-stuttgart.de> wrote:
> Alex Vinokur wrote in message <79bp9c$4fb$1...@nnrp1.dejanews.com>...
[snip]

> > cout << "Constructor : "
> > << __PRETTY_FUNCTION__
> undefined identifier "__PRETTY_FUNCTION__"
> (compiler's extension ?)
>
[snip]

__FUNCTION__ and __PRETTY_FUNCTION__ are GNU CC predefines two string
variables.

Alex

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Alex Vinokur

unread,
Feb 8, 1999, 3:00:00 AM2/8/99
to
In article <slrn7bpmip....@localhost.localdomain>,

sbn...@uiuc.edu wrote:
> On 6 Feb 1999 18:36:39 -0500, Francis Glassborow
> >In article <36b9f...@10.1.1.65>, Andrei Alexandrescu
> <alexandrescua@mi
>
> >>extern const char * const ThisFile = __FILE__;
> >
[snip]

Hi,

What is the difference between :
1) const char * const variable = "ABCD";
2) const char * variable = "ABCD";
3) char * const variable = "ABCD"; // is this valid syntax?

Thanks in advance,

Monster Zero

unread,
Feb 9, 1999, 3:00:00 AM2/9/99
to
In article <79m61o$ema$1...@nnrp1.dejanews.com>, Alex Vinokur
<alexande...@telrad.co.il> wrote:

>What is the difference between :
> 1) const char * const variable = "ABCD";
> 2) const char * variable = "ABCD";
> 3) char * const variable = "ABCD"; // is this valid syntax?
>

Here's an attempt:

1) you cannot change the address to which variable is pointing nor can you
change the character at that address

variable++ //invalid, variable would point to the 'B'
*variable = 'E'; //invalid, would modify the char to which variable points

2) you cannot change the character at the address variable is pointing to,
but you can make variable point somewhere else

variable++; //valid, variable now points at 'B'
*variable = 'E'; //invalid, modifying the char to which variable points

3) you cannot change the address to which variable is pointing but you can
change the character at that address.

variable++; //invalid, variable would point to the 'B'
*variable = 'E'; //valid, now the string is "EBCD"

Aaron

Thomas Maeder

unread,
Feb 9, 1999, 3:00:00 AM2/9/99
to
> What is the difference between :
> 1) const char * const variable = "ABCD";
> 2) const char * variable = "ABCD";
> 3) char * const variable = "ABCD"; // is this valid syntax?

Variable definitions/declarations are best read from inside out.

1) variable is a constant pointer to a constant char initialized using the
literal "ABCD"; this means that
- it is not possible to modify variable (have it refer to a different
character/string)
- it is not possible to modify characters through variable (e.g. *variable
= 'a';)

2) variable is a pointer to a constant char initialized using the literal
"ABCD"; this means that
- it is possible to modify variable (have it refer to a different
character/string)
- it is not possible to modify characters through variable (e.g. *variable
= 'a';)

3) variable is a constant pointer to a character; this means that
- it is not possible to modify variable (have it refer to a different
character/string)
- it is possible to modify characters through variable (e.g. *variable =
'a';)

Nevertheless, 3) is legal, because if it were not, many existing programs
were broken. But this conversion is "deprecated"; it shouldn't be used in
"new" code.

Francis Glassborow

unread,
Feb 9, 1999, 3:00:00 AM2/9/99
to
In article <79m61o$ema$1...@nnrp1.dejanews.com>, Alex Vinokur
<alexander.vi
no...@telrad.co.il> writes

>What is the difference between :
> 1) const char * const variable = "ABCD";
variable is itself immutable and the object (string literal in this
case) is immutable by dereferencing variable - because variable is
itself declared const it non-extern linkage.

> 2) const char * variable = "ABCD";
variable can be changed to point to another char or array of char but
whatever it is pointing to cannot be changed through dereferencing
variable

> 3) char * const variable = "ABCD"; // is this valid syntax?

currently legal (but deprecated) for backwards compatibility.
variable
is an immutable pointer to a mutable (array of) char. Because it
points
to a string literal any attempt to change the string will result in
undefined behaviour.


Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Jeremy Elgar

unread,
Feb 9, 1999, 3:00:00 AM2/9/99
to

Jeremy Elgar
Jeremy...@WestGeo.com

On 8 Feb 1999, Alex Vinokur wrote:

>
> Hi,


>
> What is the difference between :
> 1) const char * const variable = "ABCD";

In this case variable is a const pointer to a const char
ie the pointer can not be altered, for example
variable++ ; is invalid in this case
and also the data pointed to is const so
*variable = 'a' ; is also invalid ;

> 2) const char * variable = "ABCD";

Now only the data pointer to by variable is const
so variable++ will leave variable pointing to 'B'
but assignment throught this pointer is not allowed

> 3) char * const variable = "ABCD"; // is this valid syntax?

In this case the pointer itself is constant (variable++ is not
alloweed) although asignment through it is. And yes it si valid
syntax (well at least I belive it is any one correct me (im sure
someone
will)

Jeremy


>
> Thanks in advance,
> Alex
>
> -----------== Posted via Deja News, The Discussion Network ==----------
> http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
>

James...@dresdner-bank.com

unread,
Feb 9, 1999, 3:00:00 AM2/9/99
to
In article <79m61o$ema$1...@nnrp1.dejanews.com>,
Alex Vinokur <alexande...@telrad.co.il> wrote:

> What is the difference between :
> 1) const char * const variable = "ABCD";

Constant pointer pointing to constant characters.

> 2) const char * variable = "ABCD";

Non-constant pointer pointing to constant characters.

> 3) char * const variable = "ABCD"; // is this valid syntax?

Constant pointer pointing to non-constant characters. And while the
syntax is legal, the actual initializer isn't, since you cannot assign
a
char const* to a char*.

--
James Kanze GABI Software,
Sàrl
Conseils en informatique orienté objet --
-- Beratung in industrieller
Datenverarbeitung
mailto: ka...@gabi-soft.fr mailto:
James...@dresdner-bank.com

Alex Vinokur

unread,
Feb 9, 1999, 3:00:00 AM2/9/99
to
In article <79d3m4$h9q$1...@infosun2.rus.uni-stuttgart.de>,
"Thiemo Seufer" <seu...@csv.ica.uni-stuttgart.de> wrote:
> Alex Vinokur wrote in message <79bp9c$4fb$1...@nnrp1.dejanews.com>...
> [older replies snipped]

>
[snip]
> > cout << "Constructor : "
> > << __PRETTY_FUNCTION__
> undefined identifier "__PRETTY_FUNCTION__"
> (compiler's extension ?)
>
[snip]


__PRETTY_FUNCTION__ is predefined string variable in GNU gcc/g++.

Alex

Francis Glassborow

unread,
Feb 10, 1999, 3:00:00 AM2/10/99
to
In article <79oh0r$mei$1...@news-1.news.gte.net>, Monster Zero
<mons...@gte.net> writes

>3) you cannot change the address to which variable is pointing but you can
>change the character at that address.
>
>variable++; //invalid, variable would point to the 'B'
>*variable = 'E'; //valid, now the string is "EBCD"

It depends on your definition of 'valid'. That second line exhibits
undefined behaviour and the compiler is entitled to diagnose it (I
cannot remember if it is required to compile the code if it cannot prove
that the line will always be executed.)

Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

William Roeder

unread,
Feb 11, 1999, 3:00:00 AM2/11/99
to
Thomas Maeder wrote:
>
> > What is the difference between :
> > 1) const char * const variable = "ABCD";
> > 2) const char * variable = "ABCD";
> > 3) char * const variable = "ABCD"; // is this valid syntax?
>
<snip>

> 3) variable is a constant pointer to a character; this means that
> - it is not possible to modify variable (have it refer to a different
> character/string)
> - it is possible to modify characters through variable (e.g. *variable =
> 'a';)
>
> Nevertheless, 3) is legal, because if it were not, many existing programs
> were broken. But this conversion is "deprecated"; it shouldn't be used in
> "new" code.

In addition if you do attempt to modify the first character, you'll get
different results on different systems. Your program may core dump
since the literal and the pointer may be in read only memory; or all
character constants 'A' are now magically 'a'.
--
Bill Roeder
If you find yourself in a hole, the first thing to do is stop diggin'.

jim.h...@leitch.com

unread,
Feb 11, 1999, 3:00:00 AM2/11/99
to
In article <g$gtD$BEmMw...@robinton.demon.co.uk>,

Francis Glassborow <fran...@robinton.demon.co.uk> wrote:
> In article <79oh0r$mei$1...@news-1.news.gte.net>, Monster Zero
> <mons...@gte.net> writes
> >3) you cannot change the address to which variable is pointing but you can
> >change the character at that address.
> >
> >variable++; //invalid, variable would point to the 'B'
> >*variable = 'E'; //valid, now the string is "EBCD"
>
> It depends on your definition of 'valid'. That second line exhibits
> undefined behaviour and the compiler is entitled to diagnose it (I
> cannot remember if it is required to compile the code if it cannot prove
> that the line will always be executed.)

As a clarification, Francis is referring to the fact that being able to
assign a constant string pointer to a non-const pointer variable is
deprecated behaviour, i.e. in future standards the code:

char *a="ABCD";
char *const b="ABCD";

will not compile because the pointers must point to const chars.

If you write, in all the sample code in previous posts:

char test[5];
strcpy(test, "ABCD");

then substitute test for "ABCD" then all the statements in previous threads
become valid again.

Jim
Note to recruitment agencies: I will not refer my friends or colleagues
to you nor do I want to use your services to find me a job. I stop
reading unsolicited email as soon as I determine it is job-recruitment

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Miniussi

unread,
Feb 11, 1999, 3:00:00 AM2/11/99
to
James...@dresdner-bank.com wrote:
>
> In article <79m61o$ema$1...@nnrp1.dejanews.com>,
> Alex Vinokur <alexande...@telrad.co.il> wrote:
>
> > What is the difference between :
> > 1) const char * const variable = "ABCD";
>
> Constant pointer pointing to constant characters.
>
> > 2) const char * variable = "ABCD";
>
> Non-constant pointer pointing to constant characters.
>
> > 3) char * const variable = "ABCD"; // is this valid syntax?
>
> Constant pointer pointing to non-constant characters.

And maybe it's easier to remenber if you replace 1) with
char const * const var and 2) with char const * variable

then, const apply to its left hand side:
char const * : the char is const, not the pointer
char * const: the pointer is const, not the char
char const * const : both the pointer and the char are const.

> And while the
> syntax is legal, the actual initializer isn't, since you cannot assign
> a
> char const* to a char*.

Alain

Thomas Maeder

unread,
Feb 11, 1999, 3:00:00 AM2/11/99
to
James...@dresdner-bank.com wrote:
>
> > 3) char * const variable = "ABCD"; // is this valid
syntax?
>
> Constant pointer pointing to non-constant characters. And while the

> syntax is legal, the actual initializer isn't, since you cannot assign
> a char const* to a char*.

There is a deprecated conversion from a string literal to char * which
allows this initialization.

0 new messages