Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

template <char* T> class?

6 views
Skip to first unread message

Alex Vinokur

unread,
Feb 2, 1999, 3:00:00 AM2/2/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

Siemel Naran

unread,
Feb 2, 1999, 3:00:00 AM2/2/99
to
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)
----------------------------------

Peter J. Cornelius

unread,
Feb 2, 1999, 3:00:00 AM2/2/99
to
Alex Vinokur wrote:

> Hi,
>
> I need the following template class.
>
> //####################################
> #include <string>
>
> //=========================
> template <char* T>

Try tmplate <class S>

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

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

and AAA<char*> 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

A template is a general construct. If you want a specialization you first
need the general form then the apecialization would look like
template <class S> class AAA <char*>{...}

but if you want to write specializations for char* T, char[], T string S,
?, then you probably don't want a template anyway. The point of a
template is to write a general solution to handle any datatype.


--
Peter Cornelius
Lawrence Livermore National Laboratory
corne...@llnl.gov
925.423.5820
L-223


Peter J. Cornelius

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

Siemel Naran

unread,
Feb 2, 1999, 3:00:00 AM2/2/99
to
On Tue, 02 Feb 1999 09:20:51 -0800, Peter J. Cornelius

>Try tmplate <class S>

>and AAA<char*> aaa;

>A template is a general construct. If you want a specialization you first
>need the general form then the apecialization would look like
>template <class S> class AAA <char*>{...}
>
>but if you want to write specializations for char* T, char[], T string S,
>?, then you probably don't want a template anyway. The point of a
>template is to write a general solution to handle any datatype.

No, non-type arguments are allowed in templates. The most common
example is when you use an integer, eg
template <class T, size_t N> class fvector { T d_data[N]; ... };
Another common example is
enum Angle { DEGREE, RADIAN }; template <Angle> class Rotation;

Any integral builtin type qualifies as a non-type template argument.
Pointer to function, pointer to member function, pointer to object,
integer (includes bool). Using non-type template arguments like
"const char *", as opposed to a constructor that takes a
"const char *" argument, are good for enforcing greater type safety.
In some cases, we may get better runtime efficiency.

David Harmon

unread,
Feb 2, 1999, 3:00:00 AM2/2/99
to
On Tue, 02 Feb 1999 12:27:34 GMT, Alex Vinokur
<alexande...@telrad.co.il> wrote:

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

Sorry, no. Template arguments must be either typenames ("class") or int.


Peter J. Cornelius

unread,
Feb 2, 1999, 3:00:00 AM2/2/99
to
David Harmon wrote:

Huh? Do you mean
myTemplat<char*> mystring;
is illegal? And all this time I've just been blindly doing just this.

Biju Thomas

unread,
Feb 2, 1999, 3:00:00 AM2/2/99
to
David Harmon wrote:
>
> On Tue, 02 Feb 1999 12:27:34 GMT, Alex Vinokur
> <alexande...@telrad.co.il> wrote:
>
> >Can we create template classes :
> > template <char* T>
> > template <char[] T>
> > template <string S>
>
> Sorry, no. Template arguments must be either typenames ("class") or int.

No. Other non-type template arguments are allowed, such as:

-- names and addresses of of objects with external linkage
-- pointers to members
-- pointers to functions with external linkage

etc.

Also, note that only integral constants and enumerations can be used as
template arguments.

Regards,
Biju Thomas

Siemel Naran

unread,
Feb 2, 1999, 3:00:00 AM2/2/99
to
On Tue, 02 Feb 1999 11:34:51 -0800, Peter J. Cornelius
>David Harmon wrote:

>> Sorry, no. Template arguments must be either typenames ("class") or int.
>

>Huh? Do you mean
> myTemplat<char*> mystring;
>is illegal? And all this time I've just been blindly doing just this.

No, David must have meant template arguments as when you are declaring
the template class or template function. Eg,
template <class T, size_t N> class fvector;
When instantiating the template, we obviously use specific typenames
and specific integers, eg:
int main() { fvector<double,4> v; }

But other non-type arguments are indeed valid. In particular, this
is conforming:
template <const char text[]> class Thing { };
There's just one bizarre thing. When instantiating the template, the
thing we instantiate on must have external linkage. See my previous
post, and Biju's post for more details.

Alex Vinokur

unread,
Feb 3, 1999, 3:00:00 AM2/3/99
to
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)
> ----------------------------------
>

Thank you very much.
Alex

P.S. Here is a example.


//############ 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

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

Siemel Naran

unread,
Feb 3, 1999, 3:00:00 AM2/3/99
to
On Wed, 03 Feb 1999 11:48:56 GMT, Alex Vinokur

>char text1[] = "First";


>
>template <const char* T = text1> class AAA {

BTW, have you considered writing class AAA without relying on the
text field template argument, like this
class AAA {
public:
explicit AAA(std::string text);
};

Note that we use std::string instead of "char*" because std::string
has better facilities for manipulating strings.

David Harmon

unread,
Feb 3, 1999, 3:00:00 AM2/3/99
to
On Tue, 02 Feb 1999 12:55:37 -0500, Biju Thomas <biju...@ibm.net> wrote:

>> Sorry, no. Template arguments must be either typenames ("class") or int.
>

>No. Other non-type template arguments are allowed, such as:
>
> -- names and addresses of of objects with external linkage
> -- pointers to members
> -- pointers to functions with external linkage
>
>etc.
>
>Also, note that only integral constants and enumerations can be used as
>template arguments.
>
>Regards,
>Biju Thomas

I stand corrected. Indeed, that all looks like it has some very powerful
possabilities of which I was not aware.


Siemel Naran

unread,
Feb 3, 1999, 3:00:00 AM2/3/99
to
On Wed, 3 Feb 1999 16:37:43 GMT, David Harmon <sou...@netcom.com> wrote:

>I stand corrected. Indeed, that all looks like it has some very powerful
>possabilities of which I was not aware.

I'm not sure if I'd call it powerful :). I'd be happy to be proved wrong.

Alex Vinokur

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

sbn...@uiuc.edu wrote:
> On Wed, 03 Feb 1999 11:48:56 GMT, Alex Vinokur
>
> >char text1[] = "First";
> >
> >template <const char* T = text1> class AAA {
>
> BTW, have you considered writing class AAA without relying on the
> text field template argument, like this
> class AAA {
> public:
> explicit AAA(std::string text);
> };
>
> Note that we use std::string instead of "char*" because std::string
> has better facilities for manipulating strings.
>
> --
> ----------------------------------
> Siemel B. Naran (sbn...@uiuc.edu)
> ----------------------------------
>

Thank yoo very much for your help.
I always use std::string.
But in my situation (see below) I need "char*".

Karen Nelte wrote :

> 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;
> }
> //####################################
>
> =====================================================
>
> Why do you want to use a char* variable as a template parameter?
> I haven't heard of templates being able to take any parameters other
> than types, but you say template functions can? Can you show me a
> short example of this? In the above example, why don't you make "xyz"
> a parameter to the constructor instead of a template parameter?
>
> Karen
>

Why do I need to use a char* variable as a template parameter?

I designed ClassFlexibleVector
which permits flexible ranges [minIndex, maxIndex].


#######################################
### 1. ClassFlexibleVector ############
###### BEGIN ##########################
#######################################

=== 1.1 The firstClassVector.H file ===

#define LOCATION __FILE__, __LINE__, __DATE__, __TIME__

#include<string>
#include<vector>

template <typename T>
ClassFlexibleVector
{
protected :
int minExternalIndex_;
vector<T> basicUsualVector_;
// omitted

public :
ClassFlexibleVector ();

ClassFlexibleVector (
int minExternalIndex_i,
int maxExternalIndex_i,
const T& initValue_i,
const string fileName_i,
const int lineNo_i,
const string compilationDate_i,
const string compilationTime_i
)
{
// set corresponding values
}
ClassFlexibleVector& operator= (const ClassFlexibleVector&
instance_i);
// omitted
};

// omitted


=== 1.2 The first_main.C file ==========
#include "firstClassVector.H"

class AAA
{
public :
AAA () {}

~AAA () {}
ClassFlexibleVector<int> v1;
ClassFlexibleVector<int> v2;
};

int main ()
{
AAA aaa;

//=================
cout << "------ 1 ------" << endl;
aaa.v1 = ClassFlexibleVector<int> (100, 200, 0, LOCATION);
// vector range is [100 - 200];
aaa.v1 [5] = 777; // line#20

//=================
cout << "------ 2 ------" << endl;
aaa.v2 [3] = 222; // line#24

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


=== 1.3 The results of the running =

------ 1 ------
Vector Element index 5 out of range [100, 200]
Creation :
SourceFileName : first_main.C
SourceFileLineNo : 19
Compilation : Feb 4 1999 12:56:28


------ 2 ------
Vector Element index 3 out of range [0, -1]
Creation :
SourceFileName : ?
SourceFileLineNo : ?
Compilation : ?


#######################################
### 1. ClassFlexibleVector ############
###### END ############################
#######################################

So, we have no information about declaration/creation of aaa.v2
because only the ClassFlexibleVector () constructor worked.

For aaa.v1 we got the necessary information
when using operator=
aaa.v1 = ClassFlexibleVector<int> (100, 200, 0, LOCATION);

#######################################

Alex Vinokur wrote :

[snip]


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

[snip]
?

Siemel Naran 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]


#######################################
Now we can do it:

#######################################
### 2. ClassVeryFlexibleVector ########
###### BEGIN ##########################
#######################################

=== 2.1 The secondClassVector.H file ===

#include "firstClassVector.H"

#define DECLARATION theFILE_Indicator, __LINE__, theDATE_Indicator,
theTIME_Indicator

extern char theFILE_Indicator [];
extern char theDATE_Indicator [];
extern char theTIME_Indicator [];

//==========
template <typename T, this_FILE, this_LINE, this_DATE, this_TIME>
ClassVeryFlexibleVector : public ClassFlexibleVector<T>
{
private :
// omitted

public :
ClassVeryFlexibleVector () : ClassFlexibleVector<T> ()
{
// set values corresponding this_FILE, this_LINE,
this_DATE, this_TIME
}

// omitted
};

//==========
class ClassIndicator
{
public :
ClassIndicator () {}
ClassIndicator (const string& theFILE_i, const string&
theDATE_i, const string& theTIME_i)
{
strcpy (theFILE_Indicator, theFILE_i.c_str ());
strcpy (theDATE_Indicator, theDATE_i.c_str ());
strcpy (theTIME_Indicator, theTIME_i.c_str ());

}
// omitted

};

// omitted

=== 1.2 The second_main.C file ==========
#include "secondClassVector.H"

const int MAX_LENGTH_INDICATOR_File_CNS = 500;

char theFILE_Indicator [MAX_LENGTH_INDICATOR_File_CNS];
char theDATE_Indicator [MAX_LENGTH_INDICATOR_File_CNS];
char theTIME_Indicator [MAX_LENGTH_INDICATOR_File_CNS];

static ClassIndicator theClassIndicator (__FILE__, __DATE__, __TIME__);

class BBB
{
public :
BBB () {}
~BBB () {}
ClassVeryFlexibleVector<int, DECLARATION> v1; // line#16
ClassVeryFlexibleVector<int, DECLARATION> v2; // line#17
};

int main ()
{
BBB bbb;

//=================
cout << "------ 1 ------" << endl;
bbb.v1 = ClassFlexibleVector<int> (100, 200, 0, LOCATION);
// vector range is [100 - 200];
bbb.v1 [5] = 777; // line#28

//=================
cout << "------ 2 ------" << endl;
bbb.v2 [3] = 222; // line#32

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


=== 2.3 The results of the running =

------ 1 ------
Vector Element index 5 out of range [100, 200]
Declaration :
SourceFileName : second_main.C
SourceFileLineNo : 16
Compilation : Feb 4 1999 12:56:28

Creation :
SourceFileName : second_main.C
SourceFileLineNo : 22
Compilation : Feb 4 1999 12:56:28


------ 2 ------
Vector Element index 3 out of range [0, -1]
Declaration :
SourceFileName : second_main.C
SourceFileLineNo : 17
Compilation : Feb 4 1999 12:56:28

Creation : Not Created
SourceFileName : None
SourceFileLineNo : 0
Compilation : None

#######################################
### 2. ClassVeryFlexibleVector ########
###### END ############################
#######################################


To get information about
Vector Declaration and Vector Creation in header files,
we need to do additional things. It also works.


Thanks,
Alex

0 new messages