Re: Template Compile Problem
Re: Template Compile Problem
- Subject: Re: Template Compile Problem
- From: Andreas Grosam <email@hidden>
- Date: Tue, 12 Sep 2006 20:51:04 +0200
On 12.09.2006, at 18:24, Finley Lee wrote:
<x-tad-bigger>I am porting some code to XCode 2.4, and I’m having trouble getting a template function to compile. It works in other compilers; MSVC, Codewarrior, and Intel C++.</x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger>Below is a simplified example illustrating the situation. I have a static template member function in a template class, and I’m attempting to call it in a global template function. </x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger>Oddly, I get the compile error even though I’m not instantiating the global function.</x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger>Is this a problem with GCC or with me? Any advice for a workaround?</x-tad-bigger>
No, GCC is totally correct - but the other compilers may make some illegal assumptions.
You have to use the "template" keyword in order to disambiguate from other names. A (conforming) compiler is unable to recognize this by itself that you refer to a template member. Thus the compiler treats "< " as an relational operator which leads to quite confusing error messages.
The correct syntax is - as that often with template code - quite odd:
<x-tad-bigger> std::cout << template_class<U>::template template_member_fn<V>( first ) << std::endl ;</x-tad-bigger>
Similarly, if you have a class:
class A
{
public:
template<int N> int foo() const { return N; }
};
A* p = new A();
int x = p->template foo<0>();
When you omit the "template" keyword, the compiler interprets "<" as the less-than operator and foo as a non-template member - which might be defined as well.
This code will not compile:
int x = p->foo<0>();
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger>Thanks for any help.</x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger>Best regards,</x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger>Finley Lee</x-tad-bigger>
<x-tad-bigger>Alien Skin Software</x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger>/// Example begins here</x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger>#include <iostream></x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger>template < typename T ></x-tad-bigger>
<x-tad-bigger>class template_class</x-tad-bigger>
<x-tad-bigger>{</x-tad-bigger>
<x-tad-bigger>public:</x-tad-bigger>
<x-tad-bigger> static T member_fn( T in ) { return T(4) ; } </x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger> template < typename R ></x-tad-bigger>
<x-tad-bigger> static R template_member_fn( T in ) { return (R) T(3.1) ; }</x-tad-bigger>
<x-tad-bigger>} ;</x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger>template < typename U, typename V ></x-tad-bigger>
<x-tad-bigger>void do_stuff( U first, V second )</x-tad-bigger>
<x-tad-bigger>{</x-tad-bigger>
<x-tad-bigger> // ok</x-tad-bigger>
<x-tad-bigger> std::cout << "template_class<U>::member_fn( first ) == " << template_class<U>::member_fn( first ) << std::endl ;</x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger> // not ok - error: expected primary-expression before 'double'</x-tad-bigger>
<x-tad-bigger> std::cout << "template_class<U>::template_member_fn<double>( first ) == " << template_class<U>::template_member_fn<double>( first ) << std::endl ;</x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger> // not ok - error: expected primary-expression before '>' token</x-tad-bigger>
<x-tad-bigger> std::cout << "template_class<U>::template_member_fn<V>( second ) == " << template_class<U>::template_member_fn<V>( first ) << std::endl ;</x-tad-bigger>
<x-tad-bigger>}</x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger>int main (int argc, char * const argv[])</x-tad-bigger>
<x-tad-bigger>{</x-tad-bigger>
<x-tad-bigger> // ok</x-tad-bigger>
<x-tad-bigger> std::cout << "member_fn( 3 ) == " << template_class<int>::member_fn( 3 ) << std::endl ;</x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger> // ok</x-tad-bigger>
<x-tad-bigger> std::cout << "template_class<int>::template_member_fn<double>( 2.1 ) == " << template_class<int>::template_member_fn<double>( 2.1 ) << std::endl ;</x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger> return 0;</x-tad-bigger>
<x-tad-bigger>}</x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
<x-tad-bigger> </x-tad-bigger>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden