By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,512 Members | 1,701 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,512 IT Pros & Developers. It's quick & easy.

Templates, specialization

P: n/a
Here is a short code. I can't see why the template specialization does
not work (vsnet2003)? Does the standard allow these kind of
specializations?

template <int i>
class B {};

template <typename T>
class A
{
public:
void f();
};

template <typename T>
void A<T>::f()
{
}

template <int i>
void A<B<i> >::f()
{
}

int main()
{
A<B<2> > a;
a.f();

return 0;
}

--
http://kaba.hilvi.org
Oct 25 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Kalle Rutanen wrote:
Here is a short code. I can't see why the template specialization does
not work (vsnet2003)? Does the standard allow these kind of
specializations?

template <int i>
class B {};

template <typename T>
class A
{
public:
void f();
};

template <typename T>
void A<T>::f()
{
}

template <int i>
void A<B<i> >::f()
{
}

int main()
{
A<B<2> > a;
a.f();

return 0;
}


You're basically trying to partially specialize a function now; that
won't work. It does work however if you partially specialize the class,
and then define the member function out of the class. Ie. add the
following few lines:

template <int i>
class A<B<i> > {
public:
void f();
};
--
Regards,

Ferdi Smit
Email: Fe********@cwi.nl
Room: C0.07 Phone: 4229
INS3 Visualization and 3D Interfaces
CWI Amsterdam, The Netherlands
Oct 25 '05 #2

P: n/a
"Kalle Rutanen" <no**@here.com> wrote in message
news:MP************************@news.cc.tut.fi
Here is a short code. I can't see why the template specialization does
not work (vsnet2003)? Does the standard allow these kind of
specializations?
No, it doesn't.
template <int i>
class B {};

template <typename T>
class A
{
public:
void f();
};
So A has a type parameter.
template <typename T>
void A<T>::f()
{
}

template <int i>
void A<B<i> >::f()
{
}
Now, you are trying to give it a non-type parameter. This isn't really
specialization at all. It is a change in the nature of the template from one
having a type parameter to one having a non-type parameter.
int main()
{
A<B<2> > a;
a.f();

return 0;
}


Your example doesn't give much indication what you are trying to achieve.
Making a guess, something resembling what you want might be achieved
with partial specialisation, as follows:

#include <iostream>
using namespace std;

template <int i>
class B {};

template <typename T, int i=0>
class A
{
public:
void f();
};

template <typename T, int i>
void A<T,i>::f()
{
cout << "Member function of general class\n";
}

// We can't partially specialize a function,
// only a class, so we partially specialize the class
// to depend on int only

template <int i>
class A<B<i> >
{
public:
void f();
};

// Now we can define the member function of the partially
// specialized class.
template <int i>
void A<B<i> >::f()
{
cout << "Member function of partially specialized class\n";
}

int main()
{
A<char *> a1;
A<B<2> > a2;
a1.f();
a2.f();

return 0;
}
--
John Carson

Oct 25 '05 #3

P: n/a
"Ferdi Smit" <Fe********@cwi.nl> wrote in message news:Io********@cwi.nl
Kalle Rutanen wrote:
Here is a short code. I can't see why the template specialization
does not work (vsnet2003)? Does the standard allow these kind of
specializations?

template <int i>
class B {};

template <typename T>
class A
{
public:
void f();
};

template <typename T>
void A<T>::f()
{
}

template <int i>
void A<B<i> >::f()
{
}

int main()
{
A<B<2> > a;
a.f();

return 0;
}


You're basically trying to partially specialize a function now; that
won't work. It does work however if you partially specialize the
class, and then define the member function out of the class. Ie. add
the following few lines:

template <int i>
class A<B<i> > {
public:
void f();
};


Interesting code. I didn't realise it was possible. You appear to have
partially specialized class A to depend only on int when it didn't depend on
int to begin with --- at least not necessarily. Nevertheless, your code
plainly works and I see, upon checking, that Vandevoorde and Josuttis (C++
Templates) give an example (p. 351) where partial specialization involves
the introduction of a new parameter. Good to know. Thank you.
--
John Carson

Oct 25 '05 #4

P: n/a
"John Carson" <jc****************@netspace.net.au> wrote in message
news:dj***********@otis.netspace.net.au
"Kalle Rutanen" <no**@here.com> wrote in message
news:MP************************@news.cc.tut.fi
template <int i>
class B {};

template <typename T>
class A
{
public:
void f();
};


So A has a type parameter.
template <typename T>
void A<T>::f()
{
}

template <int i>
void A<B<i> >::f()
{
}


Now, you are trying to give it a non-type parameter. This isn't really
specialization at all. It is a change in the nature of the template
from one having a type parameter to one having a non-type parameter.


From Ferdi's post, I have now learned that this type of switch is indeed
possible for classes, though not for functions since it counts as a form of
partial specialization. I stand corrected.

--
John Carson

Oct 25 '05 #5

P: n/a
Hello, John and Ferdi.

It is indeed possible to specialize the class in the way Ferdi
mentioned. I am surprised too see the given situation really is
forbidden. "C++ in a nutshell", page 195: "You cannot partially
specialize a member of a class template."

But we can still explicitly specialize:

template <>
void A<B<1> >::f()
{
}

Can you think of a reason why this decision was made?

My intention is to convert pixel color formats to each other using
template meta programming (for example ARGB8888 <-> ARGB1555). You can
see the actual code here:

http://kaba.hilvi.org/project/convert/

Look at imageformatconvert.h and imageformatconvert.inl. There (.h) I
had to explicitly specialize the ImageFormatConvert template class three
times (like Ferdi suggested), while the code for them is practically
identical.

--
http://kaba.hilvi.org
Oct 25 '05 #6

P: n/a
Kalle Rutanen wrote:
Hello, John and Ferdi.

It is indeed possible to specialize the class in the way Ferdi
mentioned. I am surprised too see the given situation really is
forbidden. "C++ in a nutshell", page 195: "You cannot partially
specialize a member of a class template."

But we can still explicitly specialize:

template <>
void A<B<1> >::f()
{
}

Can you think of a reason why this decision was made?
You can't partially specialize functions. Instead you have overloading,
which is very powerful. Just remember: functions -> overloading, class
-> specialization. (Explicitly) specializing functions can also cause
some troubles when overloading is used as well. Prefer overloading.

My intention is to convert pixel color formats to each other using
template meta programming (for example ARGB8888 <-> ARGB1555). You can
see the actual code here:

http://kaba.hilvi.org/project/convert/

Look at imageformatconvert.h and imageformatconvert.inl. There (.h) I
had to explicitly specialize the ImageFormatConvert template class three
times (like Ferdi suggested), while the code for them is practically
identical.


You could use overloading with a tag type in your original example.

Ie. something like this (untested, top of my head):

template <int i>
struct B{};

struct default_tag {};
struct special_tag {};

template <typename T>
struct select_conversion {
typedef default_tag tag;
};

template <int i>
struct select_conversion<B<i> > {
typedef special_tag tag;
};
template <typename T>
class A {
public:
void f() {
// do common stuff

// do type specific stuff
f_(typename select_conversion<T>::tag());
}
private:
// select on overloading tag type
void f_(const default_tag& x) {}
void f_(const special_tag& x) {}
};
A<int> ai;
A<B<2> > ab;
ai.f();
ab.f();

Or something similar.

--
Regards,

Ferdi Smit (M.Sc.)
Email: Fe********@cwi.nl
Room: C0.07 Phone: 4229
INS3 Visualization and 3D Interfaces
CWI Amsterdam, The Netherlands
Oct 26 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.