Thread: Specialized template outside-class-definition problem during compile time.

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    12

    Wink Specialized template outside-class-definition problem during compile time.

    I've done an example of 'template specialization'. Here is the code:
    Code:
    // template specialization
    #include <iostream>
    
    using namespace std;
    
    // class template:
    template <class T>
    	class mycontainer {
    		private:
    			T element;
    		public:
    			// only prototype
    			mycontainer (T);
    			T increase ();
    	};
    
    // class method definition
    template <class T>
    	mycontainer<T> :: mycontainer(T arg) {
    		element = arg;
    	}
    
    template <class T>
    	T mycontainer<T> :: increase () {
    		return ++element;
    	}
    	
    // class template specialization: 
    template <> 
    	class mycontainer <char> { // specialized for char type
    		private:
    			char element;
    		public:
    			mycontainer(char arg) {
    				element = arg;
    			}
    			char uppercase() {
    				if ((element >= 'a') && (element <= 'z')) {
    					element += 'A'-'a';
    					return element;
    				}
    				return '0';
    			}
    	};
    
    // 
    int main () {
    	mycontainer<int> myint (7);
    	mycontainer<char> mychar ('j');
    	//
    	cout << myint.increase() << endl;
    	cout << mychar.uppercase() << endl;
    	//
    	return 0;
    }
    The compiler compiled this code successfully, but when I try to move the definition of the constructor and the method outside the class, the compiler cannot compile it.

    Here is the code with outside-class-definition:
    Code:
    // template specialization
    #include <iostream>
    
    using namespace std;
    
    // class template:
    template <class T>
    	class mycontainer {
    		private:
    			T element;
    		public:
    			// only prototype
    			mycontainer (T);
    			T increase ();
    	};
    
    // class method definition
    template <class T>
    	mycontainer<T> :: mycontainer(T arg) {
    		element = arg;
    	}
    
    template <class T>
    	T mycontainer<T> :: increase () {
    		return ++element;
    	}
    	
    // class template specialization: 
    template <> 
    	class mycontainer <char> { // specialized for char type
    		private:
    			char element;
    		public:
    			// only prototype
    			mycontainer(char);
    			char uppercase();
    	};
    
    // definition
    template <>
    	mycontainer<char> :: mycontainer(char arg) {
    		element = arg;
    	}
    
    template <>
    	char mycontainer<char> :: uppercase () {
    		if ((element >= 'a') && (element <= 'z')) {
    			element += 'A'-'a';
    			return element;
    		}
    		return '0';
    	}
    
    // 
    int main () {
    	mycontainer<int> myint (7);
    	mycontainer<char> mychar ('j');
    	//
    	cout << myint.increase() << endl;
    	cout << mychar.uppercase() << endl;
    	//
    	return 0;
    }
    The compiler generated these errors:
    Code:
    ... error C2910: 'mycontainer<char>::{ctor}' : cannot be explicitly specialized
    ... error C2910: 'mycontainer<char>::uppercase' : cannot be explicitly specialized
    Even when I add the 'char' between the angle, the compiler still gave errors.
    Code:
    template <char>
    	mycontainer<char> :: mycontainer(char arg) {
    		element = arg;
    	}
    
    template <char>
    	char mycontainer<char> :: uppercase () {
    		if ((element >= 'a') && (element <= 'z')) {
    			element += 'A'-'a';
    			return element;
    		}
    		return '0';
    	}
    With this code, The compiler generated these errors:
    Code:
    ... error C2244: 'mycontainer<char>::{ctor}' : unable to match function definition to an existing declaration
            definition
            'mycontainer<char>::mycontainer(char)'
            existing declarations
            'mycontainer<char>::mycontainer(const mycontainer<char> &)'
            'mycontainer<char>::mycontainer(char)'
    ... error C2244: 'mycontainer<char>::uppercase' : unable to match function definition to an existing declaration
            TemplateSpecialization3.cpp(36) : see declaration of mycontainer<char>::uppercase'
            definition
            'char mycontainer<char>::uppercase(void)'
            existing declarations
            'char mycontainer<char>::uppercase(void)'


    I use the compiler "Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86", and compile the source-code with "cl /clr *.cpp" command.

    Did anyone encounter this problem? Why? Is my second code incorrect or the compiler doesn't allow?

    Thank you very much

  2. #2
    Registered User
    Join Date
    Mar 2007
    Posts
    416
    Why do you want to specialize it? Why not make it general, and predefine a specialized case that uses chars?

    Sorry if that does not help, just a thought.

  3. #3
    Registered User
    Join Date
    Jan 2010
    Posts
    12
    Hi scwizzo, it's just a try-out to learn something more careful. The most effective way to learn something is to try it in all cases.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I don't know the why, but comment out the template<> part on your constructors in the second example and it compiles.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Jan 2010
    Posts
    12
    You are right. It can be compiled, but something is so secret here )

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I believe it has to do with the fact that your class template specializes the actual class and its functions. Since it's specialized, it's no longer a template.
    Therefore, those functions are like any normal functions, hence you don't need to put the specializing part of it there.
    Not 100% sure, however.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jan 2010
    Posts
    12

    Smile

    Quote Originally Posted by Elysia View Post
    I believe it has to do with the fact that your class template specializes the actual class and its functions. Since it's specialized, it's no longer a template.
    Therefore, those functions are like any normal functions, hence you don't need to put the specializing part of it there.
    Not 100% sure, however.
    It can be a reasonable description about what we'd seen. Maybe it's true.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Assignment issues
    By Elysia in forum C++ Programming
    Replies: 6
    Last Post: 01-13-2010, 12:55 PM
  2. how to define a static member in a template class
    By wanziforever in forum C++ Programming
    Replies: 3
    Last Post: 10-08-2009, 04:44 AM
  3. Errors including <windows.h>
    By jw232 in forum Windows Programming
    Replies: 4
    Last Post: 07-29-2008, 01:29 PM
  4. Default class template problem
    By Elysia in forum C++ Programming
    Replies: 5
    Last Post: 07-11-2008, 08:44 AM
  5. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM

Tags for this Thread