Thread: how to implement a template AVAILABLE OUTSIDE of the module !! (??)

  1. #1
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251

    how to implement a template AVAILABLE OUTSIDE of the module !! (??)

    In the following (still to be tested) I guess I have implemented a template AVAILABLE OUTSIDE of the module ?! That is a way to turn around the fact that C++ does not support it?
    Please let me know what you think about it!! Mistakes, drawbacks, etc.
    (of course i have cut out code which is not relevant for the discussion)
    Well for sure it is not nice that I have to put in the header a different declaration for every needed argument type


    Code:
    Recipes.h:
    EXTERN int LoadRecipe_Par(FILE * RecipeFile, etc., int * RecipePar);
    EXTERN int LoadRecipe_Par(FILE * RecipeFile, etc., unsigned int * RecipePar);
    EXTERN int LoadRecipe_Par(FILE * RecipeFile, etc., float * RecipePar);
    
    
    
    Recipes.cpp:
    
    int Cabled_sscanf(char * LoadString, char * VarName, int * RecipePar)
    {
    	return(sscanf(LoadString,"%s \t# \t%d",VarName, RecipePar));
    }
    int Cabled_sscanf(char * LoadString, char * VarName,unsigned int * RecipePar)
    {
    	return(sscanf(LoadString,"%s \t# \t%u",VarName, RecipePar));
    }
    int Cabled_sscanf(char * LoadString, char * VarName, float * RecipePar)
    {
    	return(sscanf(LoadString,"%s \t# \t%f",VarName, RecipePar));
    }
    
    template <class Type_Par> int LoadRecipePar(FILE * RecipeFile, int * BreakAll,int BreakAllAllowed, char * LoadString, char * VarName, Type_Par * RecipePar)
    {
    
    	int res;
    
    	if ( GetNextRecipeLine(RecipeFile, BreakAll, BreakAllAllowed, LoadString) )
    	{	
    		fclose(RecipeFile);
    		return -1; //fine file inaspettata
    	}
    		if ( (strstr(LoadString, "#HMI")==NULL) && (strstr(LoadString, "# HMI")==NULL)  && (strstr(LoadString, "#  HMI")==NULL) ) 
    		{
    
    		  res=Cabled_sscanf(LoadString, VarName, RecipePar);
    			
    				
    		  if(res!=2)
    		  {
    		         fclose(RecipeFile);
    		       printf("Problems reading Recipe at or after %hs\n",VarName);
    		      return -1;
    		  }
    
    		}
    
    		return(0);
    
    }
    
    //This way I basically have a template available outside (which is not supported by standard C++)
    int LoadRecipe_Par(FILE * RecipeFile, int * BreakAll,int BreakAllAllowed, char * LoadString, char * VarName, int * RecipePar)
    {
    	LoadRecipePar(RecipeFile, BreakAll, BreakAllAllowed, LoadString, VarName, RecipePar);
    }
    int LoadRecipe_Par(FILE * RecipeFile, int * BreakAll,int BreakAllAllowed, char * LoadString, char * VarName, unsigned int * RecipePar)
    {
    	LoadRecipePar(RecipeFile, BreakAll, BreakAllAllowed, LoadString, VarName, RecipePar);
    }
    int LoadRecipe_Par(FILE * RecipeFile, int * BreakAll,int BreakAllAllowed, char * LoadString, char * VarName, float * RecipePar)
    {
    	LoadRecipePar(RecipeFile, BreakAll, BreakAllAllowed, LoadString, VarName, RecipePar);
    }
    Last edited by mynickmynick; 08-20-2008 at 11:53 AM.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    With very few exceptions, the implementation of templates MUST be done in header files, so that the entire source of the template implementation is available to the compiler when compiling the code using the template.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    What exceptions are you thinking of?

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    If export works on your compiler you might not have to. If you know you will only be supporting certain types, you can use the template with those types in the source file to force the compiler to generate the code for those types, thus avoiding undefined reference errors.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MarkZWEERS View Post
    What exceptions are you thinking of?
    Just covering my rear end, really. For those pedants that find out that there's some obscure example where it can be done. But I guess I fell in it the other way around - I don't know of any exception.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    The exceptions are those compilers that implement full template support.
    http://www.comeaucomputing.com/techt...plates/#export

    gg

  7. #7
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    Hmm... but then the idea of delivering the shared object file or dll, together with the header files, to hide implementation details still cannot be accomplished?

    Nice site btw

  8. #8
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    If you want to separate the implementation from the interface you can do it, but it still needs to be in the same header file. So all this would be in the same file:
    Code:
    template <typename T>
    class Container
    {
    public:
       void Set( T val );
       T Get() const;
    
    private:
       T m_Val;
    };
    
    void Container::Set( T val )
    {
       m_Val = val;
    }
    
    T Container::Get() const
    {
       return m_Val;
    }
    Obviously this isn't what you want, but until most compilers add support for templates in .h & .cpp files, this is the best you can do.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MarkZWEERS View Post
    Hmm... but then the idea of delivering the shared object file or dll, together with the header files, to hide implementation details still cannot be accomplished?

    Nice site btw
    Not with templates. But the idea of templates is to support solutions for variable object types. If we for example make a linked list container object, we would expect to be able to store ANY type of data (object or otherwise) in that list, right? The only way to actually achieve that is by having the ability to FORM the code as the compiler encounters the instance of the template. Even with export of templates, the compiler would be required to know what the copy constructor of the object (for example) so that when you add an object to the list, the list can make a copy of this object. This can really only be solved by knowing the object at the time of instantiating the class for the object itself.

    DLL's and hding the implementation only works for objects that are known at compile-time of the DLL-code.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You can #include the cpp in your template header which will bring in all the functions. It's extremely nasty but it allows you to put the function definitions in a cpp file.

    I don't know if this will do exactly what you want. Since templates are fairly straightforward I'm usually not too worried about other's seeing my implementation.

  11. #11
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    For some examples of doing this sort of stuff just look how Microsofts COM objects are structured. Though its not exactly what you are asking, its a step in that direction. I think the first question you should ask yourself is if the cloak and dagger steps you are taking to conceal your code is all that necessary.

  12. #12
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by mynickmynick View Post
    In the following (still to be tested) I guess I have implemented a template AVAILABLE OUTSIDE of the module ?! That is a way to turn around the fact that C++ does not support it?
    Please let me know what you think about it!! Mistakes, drawbacks, etc.
    (of course i have cut out code which is not relevant for the discussion)
    Well for sure it is not nice that I have to put in the header a different declaration for every needed argument type
    You're not exporting templates at all, you're just exporting 3 regular functions. What those functions happen to call is irrelevant. I think it's extremely obvious what the downsides or limitations of this approach are.

    What's your definition of EXTERN? If those functions were extern "C" exported then I'd think you'd have problems, due to name clashes.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  13. #13
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    DLL's and hding the implementation only works for objects that are known at compile-time of the DLL-code.
    You can #include the cpp in your template header which will bring in all the functions. It's extremely nasty but it allows you to put the function definitions in a cpp file.
    yes, yes, I know all that, but then I do not see the use of a "full template support" compiler as CodePlug suggets..

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MarkZWEERS View Post
    yes, yes, I know all that, but then I do not see the use of a "full template support" compiler as CodePlug suggets..
    Well, it's an improvement on the current situation.

    If you want a relatively generic solution for a particular purpose [rather thane ENTIRELY generic] you can implement a DLL-based solution that provides the function for a base-class that can be derived from. This works for many things, and it is one of the solutions we use where I work to provide generic solutions using DLL's.

    But no, it doesn't work with generic instantiation - the objects must all relate to a base-class, and for example standard types (int, double, char, char * etc) do not do that. You can of course [assuming the base-class is simple enough] wrap these into a derived from base object.

    My point here is that DLL's are generally solving a particular problem - templates are often designed for a much more generic purpose. DLL's can be used for RELATED problems by expanding a base-class, but never be fully generic (and you wouldn't use templates as such in the base-implementation).

    I do not think that the idea behind templates was to allow the creation of shared libraries containing the code. Templates are there to solve some of the problems you can't solve with macros, to create generic solutions at compile-time.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    Quote Originally Posted by iMalc View Post
    You're not exporting templates at all, you're just exporting 3 regular functions. What those functions happen to call is irrelevant. I think it's extremely obvious what the downsides or limitations of this approach are.

    What's your definition of EXTERN? If those functions were extern "C" exported then I'd think you'd have problems, due to name clashes.
    my definition of EXTERN is nasty and just to avoid multiple declaration and put #include "Recipes.h" also in Recipes.cpp

    Code:
    Recipe.h:
    
    #ifndef RECIPES_CPP_
    #define EXTERN extern
    #else
    #define EXTERN 
    #endif
    
    
    EXTERN int LoadRecipe_Par(FILE * RecipeFile, int * BreakAll,int BreakAllAllowed, char * LoadString, char * VarName, int * RecipePar);
    EXTERN int LoadRecipe_Par(FILE * RecipeFile, int * BreakAll,int BreakAllAllowed, char * LoadString, char * VarName, unsigned int * RecipePar);
    EXTERN int LoadRecipe_Par(FILE * RecipeFile, int * BreakAll,int BreakAllAllowed, char * LoadString, char * VarName, float * RecipePar);
    Code:
    Recipes.cpp:
    
    #define RECIPES_CPP_
    
    #include "Recipes.h"
    
    then as above
    but in this special case I could avoid this nasty structure, delete from Recipes.cpp the code
    Code:
    #define RECIPES_CPP_
    #include "Recipes.h"
    and substitute

    Code:
    Recipe.h:
    
    
    
    extern int LoadRecipe_Par(FILE * RecipeFile, int * BreakAll,int BreakAllAllowed, char * LoadString, char * VarName, int * RecipePar);
    extern int LoadRecipe_Par(FILE * RecipeFile, int * BreakAll,int BreakAllAllowed, char * LoadString, char * VarName, unsigned int * RecipePar);
    extern int LoadRecipe_Par(FILE * RecipeFile, int * BreakAll,int BreakAllAllowed, char * LoadString, char * VarName, float * RecipePar);
    Last edited by mynickmynick; 08-21-2008 at 04:39 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  2. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 08:11 AM
  3. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM
  4. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 12:54 PM
  5. Function basics
    By sjleonard in forum C++ Programming
    Replies: 15
    Last Post: 11-21-2001, 12:02 PM