lol @ templates (working title)

Started by
16 comments, last by Mushu 17 years, 6 months ago
Quote:Original post by samv
Instead of partial template specialization, try simple overloading. This should even work in 7.1.
*** Source Snippet Removed ***

Yeah, that's what I did at first, but it had the same problem.

I think I'll twist the compiler's arm a little. Its gonna get messy in here :(
Advertisement
Whee! Got it to work. Basically, I made a special case for the expose function using the overload suggestion -
template < class R >void expose( const std::string& name, R( *func )( void ) ) {	details::CFuncStub stub;	stub.func = func;	stub.call = &details::_ArgParser<R>::parseNoArgs;	details::_addCFunc( name, stub );}template < class R, class A1 >void expose( const std::string& name, R( *func )( A1 ) ) {	details::CFuncStub stub;	stub.func = func;	stub.call = &details::_ArgParser<R>::parse<A1>;	details::_addCFunc( name, stub );}

See the difference? I took out the code for _ArgParser<R>::parse<void>, and instead made that a separate function entirely. This works because, well, in the case of no arguments we don't need a templated function and blah blah.

Anyway, thanks for all the help guys. Thankfully the solution was a lot cleaner than I thought it might end up being. w00t! :D
Good to hear it!

I see that this is the dawn of a new era, where people may begin to say the same things about VC7 that they have been saying about VC6 for some time.

We just made the 7->8 switch at work[smile]
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Ah, good call. I hadn't thought about overloading the expose function, but I thought about the ArgParse functions and realized that wouldn't work. But that's a good solution.
In VC7, if two template functions have the same signature & "name", they are considered identical. (actually, if two functions have the same ARGUEMENTS and name, you are screwed -- I don't think changing just the return value will make two template functions sufficiently different.)

Note that your "fix" is incomplete. Try making a function that returns a double and another that returns on int -- only one version of "parse" will be created (either the int or double one) and will be called in both cases.

Here are two fixes to your problem:

Solution 1:
Add an unused parameter that changes the signature of the two different versions
template < class R >struct _ArgParser {	template < class A1 >	static PyObject* parse( PyObject* args, void* func, A1* unused = 0 ) {		// body unchanged	}	template <>	static PyObject* parse<void>( PyObject* args, void* func, void* unused = 0 ) {		// body unchanged	}};


The second solution is less hacky:

template < class R >struct _ArgParser {	template<typename A1>	struct RetVal {		static PyObject* parse( PyObject* args, void* func ) {			// body unchanged		};	};	template <>	struct RetVal<void> {		static PyObject* parse( PyObject* args, void* func ) {			// body unchanged		};	};};


And change your access of parse to:
details::_ArgParser<R>::Retval<A1>::parse




Either that, or stop using VC7. :)

[Edited by - NotAYakk on September 30, 2006 10:04:30 PM]
Quote:Original post by NotAYakk
Note that your "fix" is incomplete. Try making a function that returns a double and another that returns on int -- only one version of "parse" will be created (either the int or double one) and will be called in both cases.

Wait, what? I don't see how that's possible.

Two separate class definitions should be created, _ArgParser<int> and _ArgParser<double>, because those represent the return type of the functions (which isn't a true return type - they all return a PyObject*).

I'm really sleepy right now. Anyway, each templated function (even though they have the same signature) resides in a separate class namespace, so I would assume it to be different.

If you're saying that

&_ArgParser<int>::parseNoArgs == &_ArgParser<double>::parseNoArgs

then, like PM me or something and I'll stop using VC7 altogether and burn the CDs in a giant pyre of shame. Because that's a stupidity that I honestly can't live with.

Anyway. I probably misread some part of your post because I'm really sleepy, so I'm going to quickly test to see if different overloads of _returnObject<R> are called, because I'm kind of new to templates and don't really know how to check their parameters at runtime with the debugger.

Want to sleeeeeppp....

EDIT:

It appears that two separate instances of _returnObject are created in your example, _returnObject<int> and _returnObject<double>, suggesting that the int and double versions of parse (didn't use the NoArgs one) are indeed not the same function. lolz, I probably am completely not understanding what you're trying to say then :(
Quote:I'm really sleepy right now. Anyway, each templated function (even though they have the same signature) resides in a separate class namespace, so I would assume it to be different.

If you're saying that

&_ArgParser<int>::parseNoArgs == &_ArgParser<double>::parseNoArgs

then, like PM me or something and I'll stop using VC7 altogether and burn the CDs in a giant pyre of shame. Because that's a stupidity that I honestly can't live with.


Not quite -- VC7 understood templated namespaces where fundamentally different.

What it didn't understand was that templated functions where fundamentally different, even if they had the same arguements (and maybe return type).

What I'm saying is that:


Try the following in VC7:

template<typename A>void foo() {  printf("default version! %d\n", sizeof(A));}template<>void foo<int>() {  printf("int version!\n %d\n", sizeof(A));}template<>void foo<double>() {  printf("double version!\n %d\n", sizeof(A));}int main() {  foo<char>();  foo<int>();  foo<double>();  foo<long>();}


Do you get what you expect? Last I recall using VC7, the above failed horribly.

What I'm saying is that
&foo<long> == &foo<char>


The "correct" output to the above program would be:
default version! 1int version!4double version!8default version! 4


(assuming you are compiling on a typical win32 system)
Yep, I got the correct version compiling with VC7.1 on a win32 system.

*sigh of relief* !!

This topic is closed to new replies.

Advertisement