Thread: Partial Specialization error?

  1. #1
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709

    Partial Specialization error?

    This error has me completely stumped. I've never heard of it (or had it) before.

    I've got a Write function in my Dataf class, which needs to be able to write all manner of data to the specified file, so I declared it a template function:

    Code:
    template <typename T> void Dataf::Write<T> (std::string fileName, T data)
    {
    		std::ostream	fd (fileName.c_str());
    		std::string	 errorBuf ("Error opening data file [");
    
    		if (!fd.is_open()) {
    			 errorBuf += fileName + "], make sure you have write permissions.\n";
    				KillGame (errorBuf);
    		}
    
    		fd >> data;
    }
    Only the Write function is a template, not the entire class. For reference:

    Code:
    class Dataf
    {
    		public:
    				Dataf ();
    				~Dataf ();
    
    			    std::string Read (std::string fileName);
    			 template <typename T> void Write<T> (std::string fileName, T data);
    		private:
    
    };
    Here's the exact error output:

    include/dataf.h:20: error: partial specialization `Write<T>' of function
    template
    dataf.cpp:45: error: partial specialization `Write<T>' of function template
    I took a look at this error and just said 'what?'.

    *edit*

    Ewww, I just looked at the layout. Not pretty, but I blame VIM
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  2. #2
    Nonconformist Narf's Avatar
    Join Date
    Aug 2005
    Posts
    174
    Is there any reason you're qualifying Write with <T>? Remove the red part for both your declaration and definition:
    Code:
    template <typename T> void Write<T> (std::string fileName, T data);
    Just because I don't care doesn't mean I don't understand.

  3. #3
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    Yes it wasn't there to start off with, but I get an 'undeclared function'-esque error. Write is qualified with <T> because I call it like so:

    Code:
    dfile->Write<std::string> (fileName, "Lee");
    *edit*

    Salem where are yoooooooooooo?
    Last edited by cboard_member; 09-04-2005 at 02:25 AM.
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  4. #4
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267
    what compiler are you using ? some compilers, such as VC++ 6.0, don't support template specialization. Other than that comment, my template skills are non-existant

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    If I understand what you are trying to achieve (I'm not sure I have, from the description)... try this...

    Code:
    class Dataf
    {
    		public:
    				Dataf ();
    				~Dataf ();
    
    			    std::string Read (std::string fileName);
    			 template <typename T> void Write(std::string fileName, T data);
    		private:
    
    };
    
    template <typename T> void Dataf::Write(std::string fileName, T data)
    {
    		std::ostream	fd (fileName.c_str());
    		std::string	 errorBuf ("Error opening data file [");
    
    		if (!fd.is_open()) {
    			 errorBuf += fileName + "], make sure you have write permissions.\n";
    				KillGame (errorBuf);
    		}
    
    		fd >> data;
    }
    
    
    //  do a partial specialisation here
    
    template <> void Dataf::Write(std::string filename, const char *x)
    {
          std::string temp(x);
          Write(filename, temp);
    }
    As an aside, you may wish to pass the second argument to all forms of Write() as const references. Also, by using operator <<, you are reading from the file, not writing it. Is that what you intend?

  6. #6
    Nonconformist Narf's Avatar
    Join Date
    Aug 2005
    Posts
    174
    Salem where are yoooooooooooo?
    Why are you calling for someone else? I solved your problem, but your compiler isn't smart enough to handle templates correctly. There's nothing wrong with how you call the function. So you're gonna have to find a workaround to handle ambiguous types:
    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Dataf
    {
    public:
      template <typename T> void Write (string fileName, T data);
    };
    
    template <typename T> void Dataf::Write (string fileName, T data)
    {
      cout << sizeof data << '\n';
    }
    
    template <> void Dataf::Write<string> (string fileName, string data)
    {
      cout << sizeof data << '\n';
    }
    
    int main()
    {
      Dataf d;
    
      d.Write<string>("test", "test");
      d.Write("test", "test");
    }
    Just because I don't care doesn't mean I don't understand.

  7. #7
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    Hmm I think GCC is more than capable.
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  8. #8
    Nonconformist Narf's Avatar
    Join Date
    Aug 2005
    Posts
    174
    Hmm I think GCC is more than capable.
    Hmm, apparently not. Have you tried your code on multiple compilers? I have. Including Comeau. I don't think anyone will argue that Comeau is the most conforming compiler when it comes to templates.

    By the way, sorry about snapping at you about the Salem thing. It's just really insulting to help someone and then see them immediately ask for help from someone else.
    Just because I don't care doesn't mean I don't understand.

  9. #9
    Registered User
    Join Date
    Sep 2005
    Posts
    2
    Hi,

    Try the following code:

    I removed the <T> as that should not be there, and made some fixes to your Write function.

    By the way, this does compile with gcc.

    Code:
    #include <string>
    #include <fstream>
    
    class Dataf
    {
    public:
            Dataf();
            ~Dataf();
    
            std::string Read (std::string fileName);
    
            // Removed <T> as that is used in partial specialization
            // And this is not what is being done here.
            template <typename T> void Write(std::string fileName, T data);
    };
    
    Dataf::Dataf()
    {
    }
    
    Dataf::~Dataf()
    {
    }
    
    
    // removed the <T> as that syntax is used in partial specialization
    // and that is not what is being done here.
    template <typename T> void Dataf::Write (std::string fileName, T data)
    {
                    //Changed ostream to ofstream - ofstream is an output file stream
                    std::ofstream   fd (fileName.c_str());
                    std::string      errorBuf ("Error opening data file [");
    
                    if (!fd.is_open()) {
                             errorBuf += fileName + "], make sure you have write per
    missions.\n";
                    //              KillGame (errorBuf);
                    }
    
                    // Changed >> to << as << is used for writing to a file
                    fd << data;
    }
    
    int main()
    {
       Dataf *dfile = new Dataf();
       std::string fileName("fname.out");
       dfile->Write<std::string> (fileName, "Lee");
       delete dfile;
    }
    Last edited by DaveProgrammer; 09-04-2005 at 08:04 PM.

  10. #10
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    Jeebus. whats all this about partial specialisations of template functions. They dont exist. Only template classes can be partially specialised. You may fully specialise a function template but not partially.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  11. #11
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    Quote Originally Posted by Narf
    Hmm, apparently not. Have you tried your code on multiple compilers? I have. Including Comeau. I don't think anyone will argue that Comeau is the most conforming compiler when it comes to templates.

    By the way, sorry about snapping at you about the Salem thing. It's just really insulting to help someone and then see them immediately ask for help from someone else.
    Thats ok
    Thanks to both of you.
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Testing some code, lots of errors...
    By Sparrowhawk in forum C Programming
    Replies: 48
    Last Post: 12-15-2008, 04:09 AM
  3. DX - CreateDevice - D3DERR_INVALIDCALL
    By Tonto in forum Game Programming
    Replies: 3
    Last Post: 12-01-2006, 07:17 PM
  4. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  5. Couple C questions :)
    By Divx in forum C Programming
    Replies: 5
    Last Post: 01-28-2003, 01:10 AM