Template class member function specialization

J

James Aguilar

Guys,

When I specialize a template class member function (I.e. a member
function of a template class) based on that class' type, bad things
happen. Here's some code:

---- test_header.h
#ifndef TEST_HEADER_H
#define TEST_HEADER_H

#include <iostream>

template <typename T>
class Test
{
public:
void out();
};

template <>
void
Test<char>::eek:ut()
{
std::cout << "I am a char!\n";
}

template <typename T>
void
Test<T>::eek:ut()
{
std::cout << "I am a T!\n";
}

#endif
----
---- test_main.cpp
#include "test_header.h"

int main()
{
Test<char> t1;
Test<int> t2;

t1.out();
t2.out();

return 0;
}
----
---- test_other.cpp
#include "test_header.h"

int test()
{
Test<char> t;
Test<int> t2;

t.out();
t2.out();
}
----
---- g++-4.1.2 reports:
../test_other.o: In function `Test<char>::eek:ut()':
.../test_header.h:15: multiple definition of `Test<char>::eek:ut()'
../test_main.o:../test_header.h:15: first defined here
----

But I thought I was supposed to put template functions and their
specializations in the header file. It works if I inline it, but I
don't *want* to inline it. In my real system, the function is a little
larger.

Any help from the gurus out there?

Grace be with you,
James Aguilar
 
A

amparikh

James said:
Guys,

When I specialize a template class member function (I.e. a member
function of a template class) based on that class' type, bad things
happen. Here's some code:

---- test_header.h
#ifndef TEST_HEADER_H
#define TEST_HEADER_H

#include <iostream>

template <typename T>
class Test
{
public:
void out();
};

template <>
void
Test<char>::eek:ut()
{
std::cout << "I am a char!\n";
}

template <typename T>
void
Test<T>::eek:ut()
{
std::cout << "I am a T!\n";
}

#endif
----
---- test_main.cpp
#include "test_header.h"

int main()
{
Test<char> t1;
Test<int> t2;

t1.out();
t2.out();

return 0;
}
----
---- test_other.cpp
#include "test_header.h"

int test()
{
Test<char> t;
Test<int> t2;

t.out();
t2.out();
}
----
---- g++-4.1.2 reports:
./test_other.o: In function `Test<char>::eek:ut()':
../test_header.h:15: multiple definition of `Test<char>::eek:ut()'
./test_main.o:../test_header.h:15: first defined here
----

But I thought I was supposed to put template functions and their
specializations in the header file. It works if I inline it, but I
don't *want* to inline it. In my real system, the function is a little
larger.

Any help from the gurus out there?

Grace be with you,
James Aguilar

Your class Test is a template class. Your function out is not a
template member function.

So

1>Either you first need to explicity specialize your class

or

2>Make your member function "out" to be a template member function and
then specialize it.

class Test
{
public:
template <typename T>
void out();
};

template<>
void Test::Out<char>()
{
}
 
J

James Aguilar

Your class Test is a template class. Your function out is not a
template member function.

So

1>Either you first need to explicity specialize your class

or

2>Make your member function "out" to be a template member function and
then specialize it.

I certainly can't do the second. The class I'm actually writing is an
iterator over a specialized container. But I want the iterator's
operator *() function to do something special, but only when it is
templatized by char. You're saying I have to reimplement the entire
class in order to change just one method? Or am I misreading you
somehow?

Yours,
James Aguilar
 
V

Victor Bazarov

James said:
Guys,

When I specialize a template class member function (I.e. a member
function of a template class) based on that class' type, bad things
happen. Here's some code:

---- test_header.h
#ifndef TEST_HEADER_H
#define TEST_HEADER_H

#include <iostream>

template <typename T>
class Test
{
public:
void out();
};

template <>

What if you just drop this "tempalate <>" thing? What you're trying
to do is to define the body of a particular function. It's not
a specialisation. Of course, since you stuck it into a header you
probably want to declare it "inline" while you're at it. Or move it
into an implemenation file to avoid multiple definition errors.
void
Test<char>::eek:ut()
{
std::cout << "I am a char!\n";
}

template <typename T>
void
Test<T>::eek:ut()
{
std::cout << "I am a T!\n";
}

#endif
----
---- test_main.cpp
#include "test_header.h"

int main()
{
Test<char> t1;
Test<int> t2;

t1.out();
t2.out();

return 0;
}
----
---- test_other.cpp
#include "test_header.h"

int test()
{
Test<char> t;
Test<int> t2;

t.out();
t2.out();
}
----
---- g++-4.1.2 reports:
./test_other.o: In function `Test<char>::eek:ut()':
../test_header.h:15: multiple definition of `Test<char>::eek:ut()'
./test_main.o:../test_header.h:15: first defined here
----

But I thought I was supposed to put template functions and their
specializations in the header file. It works if I inline it, but I
don't *want* to inline it. In my real system, the function is a
little larger.


Any help from the gurus out there?

See above.

V
 
A

amparikh

James said:
I certainly can't do the second. The class I'm actually writing is an
iterator over a specialized container. But I want the iterator's
operator *() function to do something special, but only when it is
templatized by char. You're saying I have to reimplement the entire
class in order to change just one method? Or am I misreading you
somehow?
 

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

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top