Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Template trouble



Edward:

On 29/08/2006, at 12:09 PM, Edward K. Chew wrote:

First of all, thanks for the various replies!

So, after another day of pounding on it, I was able to condense the specialization problem down to a simple example:

//__________________________________________________

#include <cstring>
#include <iostream>

namespace AccessFunctions
{
	template<typename T> int dataLength(T value)
	{
		return sizeof value;
	}

	template<typename T> int dataLength(T* value)
	{
		return sizeof(T);
	}

	template<> int dataLength(const char* str)
	{
		return std::strlen(str);
	}
}

template<typename T>
class TAccessClass
{
public:
	static int dataLength(T value)
	{
		return AccessFunctions::dataLength<T>(value);
	}
};

int main (int argc, char * const argv[]) {
	using namespace std;
	const char str[] = "Hello, world!";
	
	cout << "Case 1: ";
	cout << AccessFunctions::dataLength(str);
	cout << endl;
	
	cout << "Case 2: ";
	cout << TAccessClass<const char*>::dataLength(str);
	cout << endl;
	
	return 0;
}



First, compiling and running on Visual Studio 2005 C++ results in the same. VS2005 is fairly standards-compliant too.

Note that function templates overload, they do not partially specialize. Therefore #2 is a function overload and #3 is an explicit specialization of #2.

Let's analyze what happens in Case 2:

TAccessClass <const char*>::dataLength (str);

is a call to

AccessFunctions::dataLength <const char*> (value); // substituting const char* for the T template parameter

Therefore #1 is selected. (#2 cannot be selected since T = const char* there and the parameter would be T* = const char** -- remember, "overload and not partially specialized") -- it has nothing to do with your intermediary class TAccessClass.

Your best bet is to explictly include the trailing template parameter so that #3 becomes an explicit specialization of #1.

template<> int dataLength <const char*> (const char* str)
	{
		return std::strlen(str);
	}

If you wanted to get the function template dataLength to work as if it were partially specialized, you need to define a helper class to do that e.g.

// these are classes therefore are partially specialized

template <typename T> struct dataLength_helper
	{
		static int getsize (T value) { return sizeof (value); }
	};

template <typename T> struct dataLength_helper <T*>
	{
		static int getsize (T* value) { return sizeof (T); }
	};

template <> struct dataLength_helper <const char*>
	{
		static int getsize (const char* value) { return std::strlen (value); }
	};

// call over to the partially specialized helper
template <typename T> int dataLength (T value)
{
	return dataLength_helper <T>::getsize (value);
}


Cheers, Glen Low


--- pixelglow software | simply brilliant stuff www.pixelglow.com aim: pixglen

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/xcode-users/email@hidden

This email sent to email@hidden
References: 
 >FSRef_fopen alternative (From: "Edward K. Chew" <email@hidden>)
 >Template trouble (From: "Edward K. Chew" <email@hidden>)
 >Re: Template trouble (From: "Edward K. Chew" <email@hidden>)
 >Re: Template trouble (From: Steve Checkoway <email@hidden>)
 >Re: Template trouble (From: "Edward K. Chew" <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.