Template Member Function Specialization - Linker Error.

  • Thread starter Master of Puppets
  • Start date
M

Master of Puppets

Hi,

I am using gcc 3.2.3 20030502 (Red Hat Linux 3.2.3-34). I have having
trouble with multiple-definition linker errors when using template
member function specialization. I have created a minimal set of classes
that illustrates my problem (pardon the ridiculous names, they are for
demonstration only). I am little new to generic programming, so please
pardon my ignorance.

File: Temp.hpp
===============
#ifndef _TEMP_CLASS_H
#define _TEMP_CLASS_H

#include <iostream>

template<class T>
class Temp
{
public:
void type() const;
};

template<class T>
void Temp<T>::type() const
{
std::cout<<"Undefined"<<std::endl;
}

template<>
void Temp<int>::type() const
{
std::cout<<"Integer"<<std::endl;
}

#endif

-------

File: Use.h
============
#ifndef _USE_H
#define _USE_H

#include "Temp.hpp"

class Use
{
Temp<int> t;

public:
Use();
void print() const;
};

#endif

----------

File: Use.cpp
==============
#include "Use.h"

Use::Use(): t() {}

void Use::print() const
{
t.type();
}

---------

File:tmpMain.cpp
=================
#include "Use.h"

int main()
{
Use u;
u.print();
}

---------

When I compile and link, this is what I get:

g++ -c -Wall tmpMain.cpp -o tmpMain.o -I ./
g++ -c -Wall Use.cpp -o Use.o -I ./
g++ -o tmpMain -lm tmpMain.o ./Use.o
../Use.o(.text+0x0): In function `Temp<int>::type() const':
: multiple definition of `Temp<int>::type() const'
tmpMain.o(.text+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [tmpMain] Error 1

I don't get this error when I use the Temp class directly (without the
Use class). Am I missing something here ? I can see that I am including
Temp.hpp twice (once within Use.cpp and once within tmpMain.cpp). But,
why do I get this error ONLY when I use template specialization ? (If I
comment out the 'int' template specialization for the type() member
function, the code links properly).

Please help.

Thanks in Advance,
Vijay.
 
A

Alf P. Steinbach

* Master of Puppets:
Hi,

I am using gcc 3.2.3 20030502 (Red Hat Linux 3.2.3-34). I have having
trouble with multiple-definition linker errors when using template
member function specialization. I have created a minimal set of classes
that illustrates my problem (pardon the ridiculous names, they are for
demonstration only). I am little new to generic programming, so please
pardon my ignorance.

File: Temp.hpp
===============
#ifndef _TEMP_CLASS_H

Names starting with underscore followed by uppercase are reserved
for the implementation.

#define _TEMP_CLASS_H

#include <iostream>

template<class T>
class Temp
{
public:
void type() const;
};

template<class T>
void Temp<T>::type() const
{
std::cout<<"Undefined"<<std::endl;
}

template<>
void Temp<int>::type() const
{
std::cout<<"Integer"<<std::endl;
}

This is a definition of a function 'type' for the 'int' specialization
of template class 'Temp'.

There is, however, no such specialization of that template class.
 
M

Master of Puppets

Thanks for your response.

Does this mean that I have to define a Temp<int> class (and possibly
derive it from the general Temp<T> class and virtually overload the
type() member function) ? But, when I changed the code to the
following, it compiled and linked properly even without defining <int>
and <float> specialization classes.

#include <iostream>

template<class T>
class Temp
{
public:
void type() const;
};

template<class T>
void Temp<T>::type() const
{
std::cout<<"Undefined"<<std::endl;
}

template<>
void Temp<int>::type() const
{
std::cout<<"Integer"<<std::endl;
}

template<>
void Temp<float>::type() const
{
std::cout<<"Float"<<std::endl;
}

int main()
{
Temp<int> t1;
Temp<double> t2;
Temp<float> t3;

t1.type();
t2.type();
t3.type();
}

The output was:

Integer
Undefined
Float

-Vijay.
 
T

Thomas Maier-Komor

Master said:
Hi,

I am using gcc 3.2.3 20030502 (Red Hat Linux 3.2.3-34). I have having
trouble with multiple-definition linker errors when using template
member function specialization. I have created a minimal set of classes
that illustrates my problem (pardon the ridiculous names, they are for
demonstration only). I am little new to generic programming, so please
pardon my ignorance.

File: Temp.hpp
===============
#ifndef _TEMP_CLASS_H
#define _TEMP_CLASS_H

#include <iostream>

template<class T>
class Temp
{
public:
void type() const;
};

template<class T>
void Temp<T>::type() const
{
std::cout<<"Undefined"<<std::endl;
}

template<>
void Temp<int>::type() const
{
std::cout<<"Integer"<<std::endl;
}

this is a definition and should go into a .cpp file

replace it with

template <>
void Temp<int>::type() const;

Then it should compile and link fine...

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,692
Latest member
JenniferTi

Latest Threads

Top