CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Oct 2009
    Posts
    4

    [RESOLVED] Template Specialization in 2008

    I have now been crawling the web and these forums for hours without finding any answers...
    I am attempting to implement template specialization on a string conversion function, the project has multiple TU so of course I receive multiply-defined errors if I define the specializations in my header, now here's the rub: I have it from multiple sources (MSDN among them) that there are two solutions to this, inlining and separating the definition from the declaration, however I have yet to find a single example of the second anywhere on the internet. I would really rather not inline the code yet as I am nowhere near the optimization phase, not to look a gift horse in the mouth. Here is what I have now (abbreviated), the form of the separated definition is just extrapolation on my part. Fatal errors occur during compilation:
    Code:
    String.h
    
    //Tested and works excellent for built-ins
    template <typename T>
    String format(const T& val, const String& tag)
    {
    	//Do lots of Work Here
    	return str;
    }
    
    //Template Specialization to format a Position parameter
    template <>
    String format<Position>(const Position& val, const String& tag);
    Code:
    String.cpp
    
    //Template Specialization to format a Position parameter
    template <>
    String format<Position>(const Position& val, const String& tag)
    {
    	//Code Here (Tested separately, works well)
    }
    1>Compiling...
    1>String.cpp
    1>c:\users\tim\documents\visual studio 2008\projects\bleak\ogretest\string.cpp(17) : error C2912: explicit specialization; 'Bleak::String Bleak::format<Bleak::Position>(const Bleak::Position &,const Bleak::String &)' is not a specialization of a function template
    1>c:\users\tim\documents\visual studio 2008\projects\bleak\ogretest\string.cpp(17) : fatal error C1903: unable to recover from previous error(s); stopping compilation

    Any guidance would be much appreciated.

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Template Specialization in 2008

    The first thing you should do is rename your header file.

    There already is a standard header called <string.h>, and naming your header with the same name should not be done. Not only does it confuse other programmers looking at your code, it could confuse the compiler as well.

    Secondly, you should post the minimal, full example that doesn't compile. We do not know what String and Position are.

    Here is code that compiles perfectly fine using the Comeau C++ compiler and Visual Studio 2005:
    Code:
    template <typename T>
    int format(const T& val, const int& tag)
    {
        return 0;
    }
    
    template <>
    int format<int>(const int& val, const int& tag);
    
    template <>
    int format<int>(const int& val, const int& tag)
    {
       return 0;
    }
    I replaced all of the String and Position with int, just to get a clean compile.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; October 26th, 2009 at 01:49 PM.

  3. #3
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Template Specialization in 2008

    Try this
    Code:
    //Template Specialization to format a Position parameter
    template <>
    String format(const Position& val, const String& tag)
    {
    	//Code Here (Tested separately, works well)
    }
    If that doesn't work, please post a minimal but complete example that replicates the error.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  4. #4
    Join Date
    Oct 2009
    Posts
    4

    Re: Template Specialization in 2008

    Code:
    //BleakString.h
    
    #include <string>
    #include <sstream>
    
    //Return a String with a tag and delimiters, from a value
    //Return a null string if the tag contains the delimeters ']' or ']'
    //or if the value fails to insert into a std::stringstream
    template <typename T>
    String format(const T& val, const String& tag)
    {
    	//Create a std::string for the return value
    	std::string str = "";
    	//Create a string from the passed value
    	std::string valStr(toString(val));
    	//If the parsed value does not contain the delimeters
    	if (valStr.find_first_of("[]") == valStr.npos)
    	{
    		//If the tag does not contain the delimeters and is not empty
    		if ((tag.find_first_of("[]") == tag.npos) && (tag != ""))
    		{
    			//Build the return string starting with the tag
    			str = tag;
    			//Append the open delimeter
    			str += '[';
    			//Append the value String
    			str += valStr;
    			//Append the close delimeter
    			str += ']';
    		}
    	}
    	//Return the string
    	return str;
    }
    
    template <>
    String format<int>(const int& val, const String& tag);
    Code:
    //BleakString.cpp
    
    #include "BleakString.h"
    
    template <>
    String format(const int& val, const String& tag)
    {
    	return "";
    }
    Fails to compile with the "is not a function template specialization" above, sorry I thought it made sense. Before I added the specializations (which I use only for my defined types, but I have used int here for simplicity) everything worked fine, it is only the cpp file that produces errors.

    Thanks for the suggestions, removing template parameter (i.e. "String format()" instead of "String format<type>()") does not remove the error, but it does make it non-fatal. So compilation attempts to continue, but obviously can't succeed.
    Last edited by bimmy47; October 26th, 2009 at 02:47 PM. Reason: Forgot the include

  5. #5
    Join Date
    Oct 2009
    Posts
    4

    Re: [RESOLVED] Template Specialization in 2008

    *sighs deeply*
    sometimes I truly hate namespaces, thank you for attempting to help, of course you could not catch my stupid mistake because I forgot to include the namespace declarations, the proper code is as follows:
    Code:
    //BleakString.h
    
    #include <string>
    #include <sstream>
    
    namespace Bleak
    {
        //Return a String with a tag and delimiters, from a value
        //Return a null string if the tag contains the delimeters ']' or ']'
        //or if the value fails to insert into a std::stringstream
        template <typename T>
        String format(const T& val, const String& tag)
        {
    	//Create a std::string for the return value
    	std::string str = "";
    	//Create a string from the passed value
    	std::string valStr(toString(val));
    	//If the parsed value does not contain the delimeters
    	if (valStr.find_first_of("[]") == valStr.npos)
    	{
    		//If the tag does not contain the delimeters and is not empty
    		if ((tag.find_first_of("[]") == tag.npos) && (tag != ""))
    		{
    			//Build the return string starting with the tag
    			str = tag;
    			//Append the open delimeter
    			str += '[';
    			//Append the value String
    			str += valStr;
    			//Append the close delimeter
    			str += ']';
    		}
    	}
    	//Return the string
    	return str;
        }
    
        template <>
        String format<int>(const int& val, const String& tag);
    };
    Code:
    //BleakString.cpp
    
    #include "BleakString.h"
    
    template <>
    String Bleak::format(const int& val, const String& tag)
    {
    	return "";
    }
    I am thoroughly disappointed in myself. lol. On another note though, it would be incredibly helpful if that compiler error were more specific.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured