C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Template Specialization

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Keshav
Guest





PostPosted: Thu May 17, 2007 1:00 pm    Post subject: Template Specialization Reply with quote



templates.h

#pragma once

template<class T>

class Stack {

public:

Stack(int i = 10);

~Stack() {delete [] mStackPtr;}

int push(T value);

int Pop(T val);

private:

int size;

int top;

T *mStackPtr;



};





template<class T>

Stack<T>::Stack(int i)

{

top = 0;

size = i;

mStackPtr = new T[size];

}





template<class T>

int Stack<T>::push(T value)

{

mStackPtr[++top] = value;

return 1;

}



template<class T>

int Stack<T>::Pop(T val)

{

if (top) {

val =mStackPtr[top--];

}

return 1;

}



// Specializatiom

template<>

class Stack<char>

{

public:

int push(char a);

int Pop(char a);

private:

int size;

int top;

char *mStackPtr;

};



int Stack<char>::push(char value)

{

mStackPtr[++top] = value;

return 1;

}



int Stack<char>::Pop(char val)

{

if (top) {

val =mStackPtr[top--];

}

return 1;

}









SecondFile.cpp

#include"templates.h"





templates.cpp



#include"templates.h"

int main()

{

Stack<int> abc;

abc.push(1);

abc.push(2);

return 0;

}









Why this program is giving linking error

If I remove inclusion in SecondFile .cpp file then it works fine
If remove specialization of Stack class then it works fine


Any particular reason, std says anything regd this?

Linker Error are

Stack<char>:: push(char)" (?push@?$Stack@D@@QAEHD@Z) already defined
in templates.obj

Stack<char>::Pop(char)" (?Pop@?$Stack@D@@QAEHD@Z) already defined in
templates.obj


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Daniel Krügler
Guest





PostPosted: Fri May 18, 2007 4:13 pm    Post subject: Re: Template Specialization Reply with quote



Keshav schrieb:
Quote:
template<class T

class Stack {

public:

Stack(int i = 10);

Consider to make this c'tor explicit, otherwise the
user might stumble accross unexpected conversions.

Quote:
~Stack() {delete [] mStackPtr;}

Severe problem: You are violating the "rule of three".
In this case you have provided the d'tor (to clean up
the memory), but this class will brutaly fail to work
in any copy situation. Go ahead and define copy c'tor
and copy assignment operator (or declare them as
private)

Quote:
int push(T value);

int Pop(T val);

Consider to use some systematic naming scheme
for class members. *nix-like style (also Java) use the
initial-lower-case-camel-case system or initial-lower-
parts-separated_by_underscores, in many Windows
style guides all member functions have to start with
capital letters. Decide for any style you like (if you not
already enforced by one by your environment) - but
keep with that! It's easier for client-code to use
your code.

Quote:
template<class T

Stack<T>::Stack(int i)

{

top = 0;

size = i;

mStackPtr = new T[size];

}

Consider to use the c'tor initializer list in this
case.

Quote:
template<class T

int Stack<T>::push(T value)

{

mStackPtr[++top] = value;

return 1;

}

What is the benefit to return constantly a 1?
Nowadays this is some form of anachronism,
because C++ and C support the void return type
(which is a "procedure" in some other languages).
Either return void or some useful information.

Quote:
template<class T

int Stack<T>::Pop(T val)

{

if (top) {

val =mStackPtr[top--];

}

return 1;

}

Same proposal for the return type. A more
severe problem is, that the assignment to the
function argument val has effectively no effect.
You should change it's type to become a reference,
e.g.

void Stack<T>::Pop(T& val);

Quote:
int Stack<char>::push(char value)

{

mStackPtr[++top] = value;

return 1;

}

int Stack<char>::Pop(char val)

{

if (top) {

val =mStackPtr[top--];

}

return 1;

}

Same thing with return types and with
the val_is_not_a_reference_type problem.

Your linker problem begins here, because you
provided *non-inline* function definitions in the
header. If this header is used more than one time
in your program (it does as your latter code shows),
you provide multiple definitions of a given entity, this
is a violation of the so-called one-definition-rule
(ODR), namely 3.2/3:

"Every program shall contain exactly one definition
of every non-inline function or object that is used in
that program; no diagnostic required.[..]"

Para 5 explains why you are not enforced to fulfill
the same with the class template member functions:

"There can be more than one definition of a class
type [..] member function of a class template (14.5.1.1),
or template specialization for which some template
parameters are not specified (14.7, 14.5.4) in a program
provided that each definition appears in a different
translation unit, and provided the definitions satisfy
the following requirements.[..]"

To fix the problem, either define them in the cpp
or change them to inline functions.

Greetings from Bremen,

Daniel Krügler



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Keshav
Guest





PostPosted: Fri May 18, 2007 4:14 pm    Post subject: Re: Template Specialization Reply with quote



{ Edits: quoted clc++m banner removed. Please don't quote signatures or
the clc++m banner, and please don't top-post (see FAQ item 5.4). -mod }

Just copy paste the code and run in VS 8. U will get these errors.
These are not due to instatiation but specialization of Stack with
char datatype.
On May 18, 4:56 pm, Abhishek Padmanabh <abhishek.padman...@gmail.com>
wrote:
Quote:
On 17 May, 18:00, Keshav <gupta.kes...@gmail.com> wrote:

Linker Error are

Stack<char>:: push(char)" (?push@?$Stack@D@@QAEHD@Z) already defined
in templates.obj

Stack<char>::Pop(char)" (?Pop@?$Stack@D@@QAEHD@Z) already defined in
templates.obj

Those linker errors are impossible as nowhere do I see an
instantiation of a Stack<char> happening in the visible code.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.