Archived

This topic is now archived and is closed to further replies.

Crispy

templated functions

Recommended Posts

Hi, I don''t use templated functions at all that much, but sometimes there''s just no way around. The following thing just popped up and I''m a bit concerned about the strict implications it might have. Consider the following snippet:
  
template <class T, class varType>
T* Func(T* p1, varType p2, varType p3, varType p4) { ... }


//this will compile ok

int* Sth, p1, p2, p3;

int A* = Func(Sth, p1, p2, p3);

//but this won''t

int* Sth, p1, p2;
short p3;

int A* = Func(Sth, p1, p2, p3);
  
Admittedly, this is a good failsafe mechanism, but in some instances calls for casting which isn''t necessarily a good thing. Futhermore, declaring Func() as: template T* Func(T* p1, int p2, int p3, int p4) { ... } won''t allow the second call to Func() to compile either, which is, to me at least, somewhat logical, but then again not. Is there some way around this that doesn''t rely on casting or should I supply some extra notes with the library I will have to ship the functions in? Additionally, I''ve read that templated functions should (preferably) be defined in header files rather than source files. Is this simply a good habit or are there some more practical reasons? Conseqently, what if I don''t want to release the function body code? Thanks, Crispy

Share this post


Link to post
Share on other sites

  
template <class T, class varType2, class varType3, class varType4>T* Func(T* p1, varType2 p2, varType3 p3, varType4 p4) { ... }


That work?

if you want automatic casting, this is arcane but should work:


  
//Prototype...wherever you have it...

template <class T, class varType>T* RealFunc(T* p1, varType p2, varType p3, varType p4);

//Function that people 'use' (should be prototyped...)

template <class T, class varType2, class varType3, class varType4>T* Func(T* p1, varType2 p2, varType3 p3, varType4 p4)
{
RealFunc<T, varType2>(p1, p2, (varType2)p3, (varType2)p4);
}

//Function that does the work (you've allready written?)

template <class T, class varType>T* RealFunc(T* p1, varType p2, varType p3, varType p4) { ... }



That is how I'd do it...then again, everyone yells at me for writing unreadable code...

edit: gah...source, not code...

[edited by - MaulingMonkey on March 3, 2003 8:22:48 PM]

Share this post


Link to post
Share on other sites
about the templatized functions...

I actually think that ALL functions should be prototyped in the header. That is, functions to be used outside of the single file. This means you can compile the cpp file, also, to lib files, and yet you can still use the functions just by including the allready made .h file. Case example:

MYCOOLFUNCS.H

  
//prototype functions that everyone should be able to use

int Add(int x, int y);
void PrintLargeM(void);


MYCOOLFUNCS.CPP

  
#include <iostream>
using namespace std;

#include "MYCOOLFUNCS.H"
//prototype functions only this file should be able to use

void PrintLargeMLine1(void);
void PrintLargeMLine2(void);
void PrintLargeMLine3(void);

int Add(int x, int y)
{
return x+y;
}
void PrintLargeM(void)
{
PrintLargeMLine1();
PrintLargeMLine2();
PrintLargeMLine3();
}
void PrintLargeMLine1(void)
{
cout << "MMMMM" << endl;
}
void PrintLargeMLine2(void)
{
cout << "M M M" << endl;
}
void PrintLargeMLine3(void)
{
cout << "M M M" << endl;
}


Now pretend we''ve compiled the cpp file into a lib for easy distribution...we still have access to the .h file. We want to compile MAIN.cpp (with lib file linked on the command line...)

MAIN.cpp

  
#include <iostream>
using namespace std;

#include "MYCOOLFUNCS.H"

int main(int argc, char **argv)
{
cout << "MyCoolFuncs.h Test" << endl;
cout << "2 + 3 = " << Add(2,3) << endl;
cout << "Print Large M:" << endl;
PrintLargeM(); //Compiles okay, we print an M

cout << "Print Large M Line 1:" << endl;
PrintLargeMLine1(); //ERROR COMPILING:

// we never prototyped this, and so we have no way

// of knowing this even exists...even though we have

// the lib file linked that includes this function.

}

Share this post


Link to post
Share on other sites

    
template <class T, class varType>
T* Func(T* p1, varType p2, varType p3, varType p4) { ... }


//this will compile ok

int* Sth, p1, p2, p3;

int A* = Func(Sth, p1, p2, p3);

//but this won''t

int* Sth, p1, p2;
short p3;

int A* = Func(Sth, p1, p2, p3);



Is it me, or this simply can''t compile??? int A* = ... should be int * A = ...

Try that. I imagine the compiler will simply warn you about the widening conversion that will take place, but it should compile.

Share this post


Link to post
Share on other sites
quote:
Original post by Crispy
Additionally, I''ve read that templated functions should (preferably) be defined in header files rather than source files. Is this simply a good habit or are there some more practical reasons? Conseqently, what if I don''t want to release the function body code?


Here are some articles describing the current state of the art of separate compilation for template functions.

http://www.gotw.ca/publications/mill23.htm
http://www.gotw.ca/publications/mill24.htm

(Long story short, you''re probably stuck with defining template functions in the header.)

Share this post


Link to post
Share on other sites
MaulingMonkey: thanks for the tip - didn''t think of proviging a separate class for each of the variables.

Bashar: obviously a typo in the posted code, but thanks for pointing that out anyway.

SiCrane: ok, I see. Nevertheless I''m still reluctant to publish the code, so I figured I''d declare any feasible prototypes in the header, providing declarations for only those functions that "include" others by parameter type (eg short effectivley falls in the rage of int so there''s no real need for the short version), and call the long templated function within the library.

Thanks for your replies,
Crispy

Share this post


Link to post
Share on other sites