chsalvia
asked on
Template Specialization of Nested Class
I understand that template specializations are only valid in the namespace scope. So, in order to specialize a nested class, you need to define the specialization outside the class declaration.
Here, I try to specialize a nested class inside a templated class:
template <class T>
class A
{
template <bool B>
struct Test;
};
template <class T>
template<>
struct A<T>::Test<true> { };
However, the above code doesn't compile. Is there something wrong with my syntax?
Here, I try to specialize a nested class inside a templated class:
template <class T>
class A
{
template <bool B>
struct Test;
};
template <class T>
template<>
struct A<T>::Test<true> { };
However, the above code doesn't compile. Is there something wrong with my syntax?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
>> either you do the specialization inside of the class:
I don't think you can do this. Template specialization only seems to work in the namespace scope.
I don't think you can do this. Template specialization only seems to work in the namespace scope.
In my view, none of this would be good code:
1) it is not readable
2) it really doesn't serve any purpose, certainly not one that could be done differently
3) it may use some Microsoft specific extensions
1) it is not readable
2) it really doesn't serve any purpose, certainly not one that could be done differently
3) it may use some Microsoft specific extensions
>> "'specialization' : an explicit specialization of a template member must be a member of an explicit specialization"
mh .. the following works with VC8:
template <class T>
class A
{
public:
template <class B>
struct Test
{
Test() { printf( "no specialization\n" ); }
B val;
};
template <>
struct Test<bool>
{
Test() { printf( "specialization called\n" ); }
bool val;
};
};
int main
{
class A<int>::Test<bool> C;
class A<int>::Test<int> D;
return 0;
}
output is:
specialization called
no specialization
so it seems to work ..
ike
mh .. the following works with VC8:
template <class T>
class A
{
public:
template <class B>
struct Test
{
Test() { printf( "no specialization\n" ); }
B val;
};
template <>
struct Test<bool>
{
Test() { printf( "specialization called\n" ); }
bool val;
};
};
int main
{
class A<int>::Test<bool> C;
class A<int>::Test<int> D;
return 0;
}
output is:
specialization called
no specialization
so it seems to work ..
ike
ASKER
It doesn't work on GCC 4. Maybe it's a Microsoft extension
>> >> either you do the specialization inside of the class:
>>I don't think you can do this. Template specialization only seems to work in the namespace scope.
run the code from my last post .. ;)
>>I don't think you can do this. Template specialization only seems to work in the namespace scope.
run the code from my last post .. ;)
>> It doesn't work on GCC 4. Maybe it's a Microsoft extension
can you post the error-message?
can you post the error-message?
>> the following works with VC8
It's wrong, gcc4 is right! The standard states the specialization should only take place at namespace level -- VC8 (like in many other areas) ignores this!
>> can you post the error-message?
error: explicit specialization in non-namespace scope 'class A<T>'
The compiler will not allow the template specialization of Test because the enclosing class of class A is not explicitly specialized. Basically, as jkr has already stated, you need to specialize the outer before you can specialize the inner.
error C3212: 'A<T>::Test<true>' : an explicit specialization of a template member must be a member of an explicit specialization
It's wrong, gcc4 is right! The standard states the specialization should only take place at namespace level -- VC8 (like in many other areas) ignores this!
>> can you post the error-message?
error: explicit specialization in non-namespace scope 'class A<T>'
The compiler will not allow the template specialization of Test because the enclosing class of class A is not explicitly specialized. Basically, as jkr has already stated, you need to specialize the outer before you can specialize the inner.
error C3212: 'A<T>::Test<true>' : an explicit specialization of a template member must be a member of an explicit specialization
You can most likely achieve what you want by partial specialization of A, thus: -
#include <iostream>
template <class T, bool B>
struct A
{
struct Test;
};
template <class T>
struct A<T, true>
{
struct Test
{
static bool foo() { return true; }
};
};
template <class T>
struct A<T, false>
{
struct Test
{
static bool foo() { return false; }
};
};
int main ()
{
std::cout << "true = " << A<int, true>::Test::foo() << std::endl;
std::cout << "false = " << A<int, false>::Test::foo() << std::endl;
}
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
template <class T>
class A
{
public:
template <class B>
struct Test
{
B val;
};
template <>
struct Test<bool>
{
bool val;
};
};
or you need to specialize both template-parameters:
template <class T>
class A
{
public:
template <class B>
struct Test
{
B val;
};
};
template<>
template<>
struct A<int>::Test<bool>
{
bool val;
};
ike