?
Solved

Template Specialization of Nested Class

Posted on 2007-11-23
12
Medium Priority
?
499 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +2
12 Comments
 
LVL 19

Assisted Solution

by:SteveH_UK
SteveH_UK earned 200 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 400 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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
 

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 400 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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
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 technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses
Course of the Month11 days, 12 hours left to enroll

752 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