Sign in to follow this  
GorbGorb

template specialization problem

Recommended Posts

GorbGorb    112
Hello,

I've a problem with a specialization of template member of a template class. Here is what I want to do:

[code]

template<class X>
class A
{
template<class Y>
void func();
template<>
void func<X>();
};

[/code]

This code compiles (and works) with Visual C++, but according to the standard, it's wrong: If a template member of a template class is specialized, it has to be done in the namespace the class was defined. I tried to work around that, but I can't figure out how:
I tried
[code]
template<class X>
class A
{
template<class Y>
void func();
};
template<> template<class Y>
void A<Y>::func<Y>();
[/code]
and
[code]
template<class X>
class A
{
template<class Y>
void func();
};
template<class X> template<>
void A<X>::func<X>();
[/code]
, but both versions don't work.

Does anybody have a solution for what I want to achieve?

Share this post


Link to post
Share on other sites
sprite_hound    461
If I'm not mistaken, you can't actually specialize the member template unless you specialize the class itself first:

[source lang="cpp"]


namespace foo {

template<class X>
class A
{
public:
template<class Y>
void func();
};

template<class X> template<class Y>
void A<X>::func() {
std::cout << "unspecialized, unspecialized" << std::endl;
}

template<>
class A<int>
{
public:
template<class Y>
void func();
};

template<class Y>
void A<int>::func() {
std::cout << "specialized, unspecialized" << std::endl;
}

template<>
void A<int>::func<int>() {
std::cout << "specialized, specialized" << std::endl;
}

} // foo


int main(int, char*[])
{
using namespace foo;

A<float> af;
af.func<float>();
af.func<int>();

A<int> ai;
ai.func<float>();
ai.func<int>();

// output:
// unspecialized, unspecialized
// unspecialized, unspecialized
// specialized, unspecialized
// specialized, specialized
}

[/source]

Note that you might be able to work around it with type-to-type mapping and overloading, something like the following:

[source lang="cpp"]


namespace foo {

template<class X>
class A
{
public:
template<class Y>
void func() {
foo::func(*this, Loki::Type2Type<Y>());
}
};

template<class X, class Y>
void func(A<X> const& a, Loki::Type2Type<Y>) {
std::cout << "unspecialized, unspecialized" << std::endl;
}

//template<class X>
//void func(A<X> const& a, Loki::Type2Type<int>) {
// std::cout << "unspecialized, specialized" << std::endl;
//}

template<class Y>
void func(A<int> const& a, Loki::Type2Type<Y>) {
std::cout << "specialized, unspecialized" << std::endl;
}

void func(A<int> const& a, Loki::Type2Type<int>) {
std::cout << "specialized, specialized" << std::endl;
}

} // foo

// Loki::Type2Type is just this:
//template<typename T>
//struct Type2Type {
// typedef T OriginalType;
//};

int main(int, char*[])
{
using namespace foo;

A<float> af;
af.func<float>();
af.func<int>();

A<int> ai;
ai.func<float>();
ai.func<int>();

// output:
//unspecialized, unspecialized
//unspecialized, unspecialized
//specialized, unspecialized
//specialized, specialized
}
[/source] Edited by __sprite

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this