Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 534
  • Last Modified:

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?
0
chsalvia
Asked:
chsalvia
  • 4
  • 3
  • 2
  • +2
3 Solutions
 
SteveH_UKCommented:
Yes, you cannot define a structure in this way.

The structure must be fully defined in the class definition, but referring to B (and it should be template <class B> struct Test) in its definition.

as follows:

Also, as you can see, you cannot define a per-value (using true) definition like this.
template <class T>
class A
{
     template <class B>
     struct Test {
 
     };
};

Open in new window

0
 
jkrCommented:
MS documents that at http://msdn2.microsoft.com/en-us/library/b11ck5wk(VS.80).aspx

"'specialization' : an explicit specialization of a template member must be a member of an explicit specialization"

// C3212.cpp
// compile with: /LD
template <class T>
struct S {
   template <class T1>
   struct S1;
};


template <class T>   // C3212
template <>
struct S<T>::S1<int> {};

/*
// try the following instead
template <>
template <>
struct S<int>::S1<int> {};
*/

/*
// or, the following
template <>
struct S<int> {
   template <class T1>
   struct S1;
};

template <>
struct S<int>::S1<int> {
};
*/
0
 
ikeworkCommented:
either you do the specialization inside of the class:

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
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
chsalviaAuthor Commented:
>> 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.
0
 
SteveH_UKCommented:
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
0
 
ikeworkCommented:
>>  "'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
0
 
chsalviaAuthor Commented:
It doesn't work on GCC 4.  Maybe it's a Microsoft extension
0
 
ikeworkCommented:
>> >> 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 .. ;)
0
 
ikeworkCommented:
>> It doesn't work on GCC 4.  Maybe it's a Microsoft extension

can you post the error-message?
0
 
evilrixSenior Software Engineer (Avast)Commented:
>> 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
0
 
evilrixSenior Software Engineer (Avast)Commented:
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;
}

Open in new window

0
 
evilrixSenior Software Engineer (Avast)Commented:
>> Yes, you cannot define a structure in this way.
Refering to: -

template <bool B>
     struct Test;

That is perfectly valid code. It is declaring the existence of a template to the template compiler. If the definition of the template is never found then only the specializations of it can be instantiated.

E.g.
#include <iostream>
 
enum ACTIONS { JUMP, DUCK, UNKNOWN };
 
template <ACTIONS>
struct Action;
 
template <>
struct Action<JUMP>
{
	static void do_it()
	{
		std::cout << "Jump" << std::endl;
	}
};
 
template <>
struct Action<DUCK>
{
	static void do_it()
	{
		std::cout << "Duck" << std::endl;
	}
};
 
 
 
int main ()
{
	Action<JUMP>::do_it();
	Action<DUCK>::do_it();
 
	// This one won't compile as we've never defined the specialization
	//Action<UNKNOWN>::do_it();
}

Open in new window

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 4
  • 3
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now