Template specialization

F

Focca

I have a template function specialized with some base types:

template <typename T>
void print(const T &value);

template <>
void print<bool>(const bool &value)
{
// ...
}

template <>
void print<int>(const int &value)
{
// ...
}

Now consider a class "Value" that holds a base type (bool, int)

template <typename T>
class Value
{
public:
const T & get() const
{
return m_value;
}

T m_value;
};

When I specialize the "print" function I need to write something like this:

template <>
void print<Value<bool> >(const Value<bool> &value)
{
print(value.get());
}

template <>
void print<Value<int> >(const Value<int> &value)
{
print(value.get());
}

My question is: can I write a "template" specialized function?
I'm thinking about this:

template <>
void print<template <typename T> Value>(const Value<T> &value)
{
print(value.get());
}

or

template <typename T>
template <>
void print<Wrapper<T> >(const Wrapper<T> &value)
{
print(value.get());
}

Plz help, thanks
 
V

Victor Bazarov

Focca said:
I have a template function specialized with some base types:

template <typename T>
void print(const T &value);

template <>
void print<bool>(const bool &value)
{
// ...
}

template <>
void print<int>(const int &value)
{
// ...
}

Now consider a class "Value" that holds a base type (bool, int)

It's not a class. It's a class template. Just so we use the same terms.
template <typename T>
class Value
{
public:
const T & get() const
{
return m_value;
}

T m_value;
};

When I specialize the "print" function I need to write something like
this:
template <>
void print<Value<bool> >(const Value<bool> &value)
{
print(value.get());
}

template <>
void print<Value<int> >(const Value<int> &value)
{
print(value.get());
}

My question is: can I write a "template" specialized function?
I'm thinking about this:

template <>
void print<template <typename T> Value>(const Value<T> &value)
{
print(value.get());
}

Slightly off, but close. This should be a straight template:

template<class T>
void print(const Value<T> &value)
{
print(value.get());
}

The compiler will pick the right one and deduce 'T' for it.
or

template <typename T>
template <>
void print<Wrapper<T> >(const Wrapper<T> &value)
{
print(value.get());
}

No, this is not a proper form either. See above.

HTH

V
 
R

Rolf Magnus

Focca said:
I have a template function specialized with some base types:

template <typename T>
void print(const T &value);

template <>
void print<bool>(const bool &value)
{
// ...
}

template <>
void print<int>(const int &value)
{
// ...
}

Now consider a class "Value" that holds a base type (bool, int)

template <typename T>
class Value
{
public:
const T & get() const
{
return m_value;
}

T m_value;
};

When I specialize the "print" function I need to write something like
this:

template <>
void print<Value<bool> >(const Value<bool> &value)
{
print(value.get());
}

template <>
void print<Value<int> >(const Value<int> &value)
{
print(value.get());
}

My question is: can I write a "template" specialized function?
I'm thinking about this:

template <>
void print<template <typename T> Value>(const Value<T> &value)
{
print(value.get());
}

or

template <typename T>
template <>
void print<Wrapper<T> >(const Wrapper<T> &value)
{
print(value.get());
}

Just write:

template <typename T>
void print<Wrapper<T> >(const Wrapper<T> &value)
{
print(value.get());
}
 
P

Pierre Barbier de Reuille

Focca said:
I have a template function specialized with some base types:

template <typename T>
void print(const T &value);
[...]

My question is: can I write a "template" specialized function?
I'm thinking about this:

template <>
void print<template <typename T> Value>(const Value<T> &value)
{
print(value.get());
}

or

template <typename T>
template <>
void print<Wrapper<T> >(const Wrapper<T> &value)
{
print(value.get());
}

Plz help, thanks

Yes you can, it is called "partial specialization". But you have to
write it like that :


template <class T>
void print<Value<T> > (const Value<T> &value)
{
print(value.get());
}

Pierre
 
V

Victor Bazarov

Pierre said:
[..]
Yes you can, it is called "partial specialization". [..]

Just a reminder: partial specialisations of function templates
are not allowed in C++ (yet).

V
 
F

Focca

template said:
void print<Value<T> > (const Value<T> &value)
{
print(value.get());
}

VC2003 says -> 'print' : illegal use of explicit template arguments :(
 
V

Victor Bazarov

Focca said:
Isn't this an overload?It's not a specialization right?

It's not an overload, it's not a specialisation. It's just another
template. Function templates are weird like that. For example,

template<class T> class other {};

template<class T> int foo(T t) { return 0; }
template<class T> int foo(other<T> ot) { return 42; }

int main() {
other<int> oi;
int a = foo(666); // foo<int>(int) is picked
int b = foo(oi); // foo<int>(other<int>) is picked
}

As you can see, a more specialised template (although it is not
a specialisation) is picked for instantiation in case of 'foo(oi)'.
foo<other<T> >(other<T>) _could_ be a fit as well (by instantiating
the first 'foo' template), but the more specialised is preferred.

V
 
V

Victor Bazarov

Rolf said:
Victor said:
Rolf said:
Focca wrote:
[..]

Just write:

template <typename T>
void print<Wrapper<T> >(const Wrapper<T> &value)
{
print(value.get());
}

This looks like partial specialisation.

I think it is ;-)
Is it really going to work?

On my compiler, it did.

I am guessing now that you're just dicking around. Partial
specialisations of function templates are not allowed.
 
F

Focca

I am guessing now that you're just dicking around. Partial
specialisations of function templates are not allowed.

Tested...
VC2003 says -> 'print' : illegal use of explicit template arguments
 
V

Victor Bazarov

Focca said:
Tested...
VC2003 says -> 'print' : illegal use of explicit template arguments

Well... You might still consider upgrading, VC2005 is better, and also
whatever your compiler says doesn't necessarily reflect what the standard
says. That's why I said Rolf was dicking around. "His" compiler allowed
the construct. Doesn't mean all compilers do or *should*.

V
 
R

Rolf Magnus

Victor said:
Rolf said:
Victor said:
Rolf Magnus wrote:
Focca wrote:
[..]

Just write:

template <typename T>
void print<Wrapper<T> >(const Wrapper<T> &value)
{
print(value.get());
}

This looks like partial specialisation.

I think it is ;-)
Is it really going to work?

On my compiler, it did.

I am guessing now that you're just dicking around.

I am not!
Partial specialisations of function templates are not allowed.

Well, I didn't know (or remember) that. When trying it on my compiler, I
fooled myself by accidentally trying something similar to your suggestion.
 

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
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top