Solved

Template Specialization of Nested Class

Posted on 2007-11-23
12
458 Views
Last Modified: 2012-06-21
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
Comment
Question by:chsalvia
  • 4
  • 3
  • 2
  • +2
12 Comments
 
LVL 19

Assisted Solution

by:SteveH_UK
SteveH_UK earned 50 total points
ID: 20340436
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
 
LVL 86

Accepted Solution

by:
jkr earned 100 total points
ID: 20340454
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
 
LVL 20

Expert Comment

by:ikework
ID: 20340456
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
 

Author Comment

by:chsalvia
ID: 20340479
>> 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
 
LVL 19

Expert Comment

by:SteveH_UK
ID: 20340482
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
 
LVL 20

Expert Comment

by:ikework
ID: 20340494
>>  "'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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:chsalvia
ID: 20340500
It doesn't work on GCC 4.  Maybe it's a Microsoft extension
0
 
LVL 20

Expert Comment

by:ikework
ID: 20340512
>> >> 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
 
LVL 20

Expert Comment

by:ikework
ID: 20340516
>> It doesn't work on GCC 4.  Maybe it's a Microsoft extension

can you post the error-message?
0
 
LVL 40

Expert Comment

by:evilrix
ID: 20340694
>> 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
 
LVL 40

Expert Comment

by:evilrix
ID: 20340777
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
 
LVL 40

Assisted Solution

by:evilrix
evilrix earned 100 total points
ID: 20340804
>> 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

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now