Specialising a template member function of a template class?

I

Ian

Can it be done? If so, what's the syntax.

For example a full specialisation,

template <typename T>
struct X
{
template <typename C> void foo( C a ) {}
};

template<> template<>
void X<int>::foo<char>( char a ) { assert(0); }

int main()
{
X<int> x;
char c = 0;

x.foo( c );
}

Works fine, but

template<typename T> template<>
void X<T>::foo<char>( char a ) { assert(0); }

isn't legal.

Cheers,

Ian
 
J

John Carson

Ian said:
Can it be done? If so, what's the syntax.

For example a full specialisation,

template <typename T>
struct X
{
template <typename C> void foo( C a ) {}
};

template<> template<>
void X<int>::foo<char>( char a ) { assert(0); }

int main()
{
X<int> x;
char c = 0;

x.foo( c );
}

Works fine, but

template<typename T> template<>
void X<T>::foo<char>( char a ) { assert(0); }

isn't legal.

You're right. It isn't legal. You can only specialise template members if
the enclosing class is fully specialised.
 
B

ben

template <typename T>
struct X
{
template <typename C> void foo (C a) {}
};

template <>
struct X<int>
{
void foo(char a)
{
assert(0);
}
};

ben
 
I

Ian

John said:
You're right. It isn't legal. You can only specialise template members
if the enclosing class is fully specialised.

I thought so, where abouts in the standard is it stated, I looked, but
couldn't find a reference to specialising a template member function of
a template class.

Cheers,

Ian
 
J

John Carson

Ian said:
I thought so, where abouts in the standard is it stated, I looked, but
couldn't find a reference to specialising a template member function
of a template class.

Section 14.7.3/18:

"In an explicit specialization declaration for a member of a class template
or a member template that appears in namespace scope, the member template
and some of its enclosing class templates may remain unspecialized, except
that the declaration shall not explicitly specialize a class member template
if its enclosing class templates are not explicitly specialized as well."

You may note that this refers to specializations that appear in namespace
scope. Section 14.7.3/2 makes it clear that this is the only option:

"An explicit specialization shall be declared in the namespace of which the
template is a member, or, for member templates, in the namespace of which
the enclosing class or enclosing class template is a member."
 
I

Ian

John said:
Section 14.7.3/18:

"In an explicit specialization declaration for a member of a class
template or a member template that appears in namespace scope, the
member template and some of its enclosing class templates may remain
unspecialized, except that the declaration shall not explicitly
specialize a class member template if its enclosing class templates are
not explicitly specialized as well."

You may note that this refers to specializations that appear in
namespace scope. Section 14.7.3/2 makes it clear that this is the only
option:

"An explicit specialization shall be declared in the namespace of which
the template is a member, or, for member templates, in the namespace of
which the enclosing class or enclosing class template is a member."
Thanks John, I couldn't spot the woof for the trees!

Ian
 
I

Ian

ben said:
template <typename T>
struct X
{
template <typename C> void foo (C a) {}
};

template <>
struct X<int>
{
void foo(char a)
{
assert(0);
}
};
Cheers,

But this falls down if X and C are different types and X<C> makes no sense.

Ian
 
B

ben

I don't get what you mean. X and C are of course different, X is not even a
type (but a template).

ben
 
I

Ian

ben said:
I don't get what you mean. X and C are of course different, X is not even a
type (but a template).

ben



sense.

Sorry, my typo. It should have read "if T and C are different types".

Ian
 
B

ben

You can't specialize function templates, but you can overload functions.
This is what the code I gave you does. X<C> of course makes no sense because
there's no X<C> in my code, only X<T>. C is the parameter for the member
function template foo in the non-specialized class template X. If that is
not what you want to achieve, please tell us what exactly you want to do
with it.

For example:

X<double> x1; // non specailized template
x1.foo(int(0)); // void X<double>::foo<int>(int),
does nothing
x1.foo(MyStupidClass()); // void
X<double>::foo<MyStupidClass>(MyStupidClass), does nothing

X<int> x2; // specialized template
x2.foo(char(0)); // void X<int>::foo(char), calls
assert(0)
x2.foo(MyStupidClass()); // Error, X<int>::foo(MyStupidClass) not
defined

ben
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top