language >> Template specialization to pointers - bug or what?

by » Sun, 01 Feb 2004 00:31:47 GMT

Hello,
Take a look at this piece of code:


--------------------------------------------------


// A: PARTIAL SPECIALIZATION WORKS HERE JUST FINE: /////

template<class T, class T1>
struct A
{
T t1;
typedef T Type;
Type f() { return Type(); }
};

template<class T>
struct A<T,int> : public A<T,char> // I.E. INHERITS FROM GENERAL TYPE
{
T t2;
Type g() { return Type(); } // NO ERROR, SEE NOTE BELOW
};


// B: PROBLEM OCCURS: ///////////////////////////////////

template<class T, class T1>
struct B
{
};

template<class T,class T1>
struct B<T*,T1>
{
T* tp1;
typedef T Type;
Type f() { return Type(); }
};

template<class T>
struct B<T*,int> : public B<T*,char> // I.E. INHERITS FROM GENERAL TYPE
{
T* tp2;
// typedef typename B<T*,char>::Type Type; // WITH THIS LINE, NO ERROR
Type g() { return Type(); } // ERROR!
// IT SEEMS LIKE THIS CLASS CANNOT REACH THE TYPEDEF DEFINED IN ITS PARENT
// WITH CLASS A -NO SPECIALIZING TO POINTER TYPE- THIS WORKED.
};


int main()
{
A<int,int> a; // TYPE SPECIALIZED TO int
int f = a.f();
B<int*,int> b; // TYPE SPECIALIZED TO pointer,int
int g = b.f();
return 0;
}//main()

----------------------------------------------------------

The error message generated:
error C2146: syntax error : missing ';' before identifier 'g'
error C2501: 'B<T*,int>::Type' : missing storage-class or type specifiers


Is this a bug or some strange language feature I haven't run into before?

Thx,
Gus




language >> Template specialization to pointers - bug or what?

by John Carson » Sun, 01 Feb 2004 11:30:24 GMT




>> Hello, >> Take a look at this piece of code: >> >> >> -------------------------------------------------- >> >> >> // A: PARTIAL SPECIALIZATION WORKS HERE JUST FINE: ///// >> >> templat< >> struct A >> { >> T t1; >> typedef T Type; >> Type f() { return Type(); } >> }; >> >> templat< >> struct < : public < // I.E. INHERITS FROM GENERAL TYPE >> { >> T t2; >> Type g() { return Type(); } // NO ERROR, SEE NOTE BELOW >> }; >> >> >> // B: PROBLEM OCCURS: /////////////////////////////////// >> >> templat< >> struct B >> { >> }; >> >> templat< >> struct < >> { >> T* tp1; >> typedef T Type; >> Type f() { return Type(); } >> }; >> >> templat< >> struct < : public < // I.E. INHERITS FROM GENERAL >> TYPE { >> T* tp2; >> // typedef typename <::Type Type; // WITH THIS LINE, NO ERROR >> Type g() { return Type(); } // ERROR! >> // IT SEEMS LIKE THIS CLASS CANNOT REACH THE TYPEDEF DEFINED IN ITS >> PARENT // WITH CLASS A -NO SPECIALIZING TO POINTER TYPE- THIS >> WORKED. }; >> >> >> int main() >> { >> < a; // TYPE SPECIALIZED TO int >> int f = a.f(); >> < b; // TYPE SPECIALIZED TO pointer,int >> int g = b.f(); >> return 0; >> }//main() >> >> ---------------------------------------------------------- >> >> The error message generated: >> error C2146: syntax error : missing ';' before identifier 'g' >> error C2501: '<::Type' : missing storage-class or type >> specifiers >> >> >> Is this a bug or some strange language feature I haven't run into >> before? >> >> Thx, >> Gus

If you run your code on Comeau online (a famously standard-compliant
implementation)

http://www.comeaucomputing.com/tryitout/

then you will find that both your A and B versions fail. The fact that A
succeeds on VC++ is non-standard. Apparently it has to do with the
complicated lookup rules for templates.

Section 14.6.2, p 3 of the C++ standard says:

"In the definition of a class template or a member of a class template, if a
base class of the class template depends on a template-parameter, the base
class scope is not examined during unqualified name lookup either at the
point of definition of the class template or member or during an
instantiation of the class template or member.
[Example:

typedef double A;

templat< class B {
typedef int A;
};

templat< struct X : <<>> {
A a; // a has type double
};

The type name A in the definition of <<>> binds to the typedef name defined
in the global namespace scope, not to the typedef name defined in the base
class <<>>. ]"

My understanding of these matters is very limited, but it seems clear that
your code should not compile.

--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)




language >> Template specialization to pointers - bug or what?

by » Mon, 02 Feb 2004 19:20:06 GMT

Hi, thank you very much for the answer, but

a
defined

Are you saying that the child of the template class must redefine the public
typedef's defined in the base? I.e. in the example above, do I have to
write:

template<class T> struct X : B<T> {
typedef typename B<T>::A A
A a; // now A is int as I intended it to be
};





Template specialization to pointers - bug or what?

by tom_usenet » Mon, 02 Feb 2004 19:51:05 GMT

On Sat, 31 Jan 2004 17:31:47 +0100, "oston Bej<< XXXX@XXXXX.COM >>

>>Hello, >>Take a look at this piece of code: >> >>// A: PARTIAL SPECIALIZATION WORKS HERE JUST FINE: ///// >> >>templat< >>struct A >>{ >> T t1; >> typedef T Type; >> Type f() { return Type(); } >>}; >> >>templat< >>struct < : public < // I.E. INHERITS FROM GENERAL TYPE >>{ >> T t2; >> Type g() { return Type(); } // NO ERROR, SEE NOTE BELOW

Should be:

typename <::Type g() { return typename <::Type();}

>>templat< >>struct < : public < // I.E. INHERITS FROM GENERAL TYPE >>{ >> T* tp2; >>// typedef typename <::Type Type; // WITH THIS LINE, NO ERROR >> Type g() { return Type(); } // ERROR! >> // IT SEEMS LIKE THIS CLASS CANNOT REACH THE TYPEDEF DEFINED IN ITS PARENT >> // WITH CLASS A -NO SPECIALIZING TO POINTER TYPE- THIS WORKED.

Same again, except with typename <::Type.
>>Is this a bug or some strange language feature I haven't run into before?

It is dependent name lookup - non-dependent names (those that don't
appear to depend on template parameters) are looked up in the context
of the definition, so the template base class can't be checked. You
have to make the dependent, in this case showing that they are type
members of the base class.

Tom

C++ FAQ: http://www.parashift.com/c ++-faq-lite/
C FAQ: http://www.eskimo.com/ ~scs/C-faq/top.html


Template specialization to pointers - bug or what?

by John Carson » Mon, 02 Feb 2004 20:22:18 GMT



>> Hi, thank you very much for the answer, but >> >>> "In the definition of a class template or a member of a class >>> template, if a base class of the class template depends on a >>> template-parameter, the base class scope is not examined during >>> unqualified name lookup either at the point of definition of the >>> class template or member or during an instantiation of the class >>> template or member. [Example: >>> >>> typedef double A; >>> >>> templat< class B { >>> typedef int A; >>> }; >>> >>> templat< struct X : <<>> { >>> A a; // a has type double >>> }; >>> >>> The type name A in the definition of <<>> binds to the typedef name >>> defined in the global namespace scope, not to the typedef name >>> defined in the base class <<>>. ]" >> >> Are you saying that the child of the template class must redefine the >> public typedef's defined in the base? I.e. in the example above, do I >> have to write: >> >> templat< struct X : <<>> { >> typedef typename <<>>::A A >> A a; // now A is int as I intended it to be >> };

Yes, exactly (except for the missing semi-colon).

--
John Carson
1. To reply to email address, remove donald
2. Don't reply to email address (post here instead)




Similar Threads

1. Template specialization of pointers with function pointers

Ok, I have a template function for any pointer to type T:

template <typename T>
void func(T* p)
{
    DoSomethingGeneric(p);
}

Can I specialize this template for pointers to functions (or pointers
to member functions, or pointers to anything)? I would like to do
something like this:

typedef void (*FUNCPTR)();

template <>
void func(FUNCPTR p)
{
    DoSomethingSpecialWithFuncPtr(p);
}

but my compiler (Visual C++ 6) won't let me. I know VC6 is lacking in
support for templates, but I'd like to know if this is even legal
anyway. Thanks.

2. [BUG]? explicit specialization of templates

3. Compiler bug w/ partial function template specialization w/ multiple parameters

Here is a very simple piece of code to repro this bug.
 
template<typename T, int N> inline bool foo( void )
{
	return true;
}

template<typename T> inline bool foo<T, 1>( void )
{
    return false;
}

the partial specialization of foo fails to compile w/:
error C2768: 'foo' : illegal use of explicit template 
arguments


I believe the above should compile fine.  At the very 
least it is inconsistent because doing the same thing 
using either 
A) classes
or
B) a template function w/ just one parameter
or
C) specializing both parameters
compiles.  i.e., all of the below compile fine


1)
template<typename T, int N> class C
{
public:
	inline static bool foo( void )
	{
		return true;
	}
};

template<typename T> class C<T, 1>
{
public:
	inline static bool foo( void )
	{
		return false;
	}
};

2)
template<> inline bool foo<float, 1>( void )
{
	return false;
}

3)
template<int N> inline bool foo( void )
{
	return true;
}

template<> inline bool foo<1>( void )
{
	return false;
}

What is the best way to submit this bug to the compiler 
group at MS?  BTW, I'm running MS VC++ 7.1.3088

Thanks,
Michael Stembera