473,394 Members | 1,956 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

function template overloading

Hi all,

i would appreciate help with the following problem: Please consider the code
Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. template<typename T> struct A{};
  5. template<typename T> struct B: public A<T>{};
  6.  
  7. template<typename T> void f(T obj){ cout << "default\n"; }
  8. template<typename T> void f(A<T> obj){ cout << "special case\n"; }
  9.  
  10. int main(){
  11.     A<int> a;
  12.     f(a);
  13.     B<int> b;
  14.     f(b);
  15. }
  16.  
This code compiles fine and produces the output
Expand|Select|Wrap|Line Numbers
  1. special case
  2. default
As you can see - and I guess that is the way it is supposed to work - the special case implementation is only used if the template fits exactly, not by inheritance.

What I would like to do, however, is specify function f for the special case that it is called with parameter of type A<T> or B<T> for any type T and any child B of A.

Is there a way to do this? Or do I have to write another template (with the same code) for the case f(B<T> obj)?

Any advise appreciated, I can't think of a good way.

~<><~~~~~~ presencia
Sep 2 '10 #1
6 1487
weaknessforcats
9,208 Expert Mod 8TB
You will need to make function f a memeber function for the special case.
Sep 2 '10 #2
I am sorry I don't get it right away. What class should f be a member of?
Why exactly do I have to make it a member function?
And can I still call it the same way as the default version? (i.e., like: f(obj) )

Thanks for your time!
~<><~~~~~~~~ presencia
Sep 2 '10 #3
weaknessforcats
9,208 Expert Mod 8TB
Is this what you had in mind? I'm not sure I have your program requirements correctly understood.

Expand|Select|Wrap|Line Numbers
  1. template<typename T> struct A
  2. {
  3.     virtual void f(A<T> obj){ cout << "special case\n"; } 
  4.  
  5. }; 
  6. template<typename T> struct B: public A<T>
  7. {
  8.     virtual void f(A<T> obj){ cout << "special case\n"; } 
  9.  
  10. }; 
  11.  
  12. template<typename T> void f(T obj){ cout << "default\n"; } 
  13.  
  14.  
  15. int main(){ 
  16.     A<int> a; 
  17.     a.f(a); 
  18.     B<int> b; 
  19.     b.f(b); 
  20.     f(a);
  21.     f(b);
Sep 5 '10 #4
Thanks for your reply.
I am afraid, I didn't explain my problem well enough. So please let me try again:

I want to write a global function that does something. I want it to take one parameter of any type or class it can deal with. So I write a function template instead of a function, just like this:
Expand|Select|Wrap|Line Numbers
  1. //first function template f
  2. template<typename T> void f(T obj){ /*do something*/ }
Everything works well for now. I can call function f with just any object.

But now I have a class template A:
Expand|Select|Wrap|Line Numbers
  1. template<typename T> struct A{};
and I would like f to behave differently if the parameter provided is of type A<T> for any typename T. So I want to overload f, just like this:
Expand|Select|Wrap|Line Numbers
  1. //second function template f
  2. template<typename T> void f(A<T> obj){ /*do a different thing*/ }
Now, when I call f with an object of type A<T> like this
Expand|Select|Wrap|Line Numbers
  1. A<int> a;
  2. f(a);
the code of the second function template f is executed, just as I wanted. But I want this "second version of f" to be executed if called with a parameter of type B<T> for any child B of A and any typename T, just like this:
Expand|Select|Wrap|Line Numbers
  1. template<typename T> struct B: public A<T>{};
  2. B<int> b;
  3. f(b);
However, executing the last code will call the FIRST version of function template f.

Now, there is a simple solution for this: I can just copy the code of template<typename T> void f(A<T> obj) and write function templates template<typename T> void f(B<T> obj) for all children B of A, all with the exact same code to be executed.

My question is: I there a way to produce the function f like I want it without making a copy of the code for every class derived from A?

Thanks for considering my question.
~<><~~~~ presencia
Sep 6 '10 #5
weaknessforcats
9,208 Expert Mod 8TB
Try:

Expand|Select|Wrap|Line Numbers
  1. template<typename T> struct A
  2. {
  3.  
  4.     virtual void f();
  5.  
  6. }; 
  7. template<class T>
  8. void A<T>::f()
  9. { cout << "A special case\n"; } 
  10.  
  11. template<typename T> struct B: public A<T>
  12. {   
  13.  
  14.     virtual void f(); 
  15.  
  16. };
  17. template<typename T>
  18. void B<T>::f(){ cout << "B special case\n"; } 
  19.  
  20. template<typename T> void f(T& obj){ cout << "default\n"; } 
  21. template<typename T> void f(A<T>* obj){ obj->f();}
  22.  
  23.  struct C
  24.  {
  25.  
  26.  };
  27. int main(){ 
  28.     A<int> a; 
  29.     B<int> b; 
  30.     f(&a);
  31.     f(&b);
  32.     C c;
  33.     f(c);
  34.  
The idea here is that when you call the global f using a pointer to get a virtual function call into the struct A hierarchy. That will call the correct f() for the child of A. When you call the global f() by reference, you get your default case.

Note the global f() overload uses a T& and an A<T>*.

You will not be able to overload the global f() using T and A<T>*. The pointer is seen as a T and you get the wrong template. However, a reference requires an object so the compiler sees A<T>* as a better fit than T& and picks the right template.

Does this work for you?
Sep 6 '10 #6
hype261
207 100+
Even though this might not be an elegant solution to your problem you could always do this.

Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2.  
  3. template<class T>
  4. struct A
  5. {
  6.  
  7. };
  8.  
  9. template<class T>
  10. struct B : public A<T>
  11. {
  12.  
  13. };
  14.  
  15. struct C
  16. {
  17.  
  18. };
  19.  
  20. template<typename T>
  21. void f( T & obj)
  22. {
  23.        std::cout << "default case" << std::endl;
  24. }
  25.  
  26. template<typename T>
  27. void f(A<T> & obj)
  28. {
  29.        std::cout << "special case" << std::endl;
  30. }
  31.  
  32. template<typename T>
  33. void f(B<T> & obj)
  34. {
  35.        A<T> * reference = dynamic_cast<A<T>*>(&obj);
  36.        if(reference != 0)
  37.        {
  38.               f(*reference);
  39.        }
  40. }
  41.  
  42. int main()
  43. {
  44.  
  45.        A<int> a;
  46.        B<int> b;
  47.        C c;
  48.  
  49.        f(a);
  50.        f(b);
  51.        f(c);
  52.  
  53.        return 0;
  54.  
  55. }
  56.  
The benefit here is that you can use don't have to remember to include the address of operator if you want to call the A<T> or B<T> template versions.
Sep 8 '10 #7

Sign in to post your reply or Sign up for a free account.

Similar topics

5
by: Arkadiy Vertleyb | last post by:
Hi all, I am having a problem trying to overload a function template, based on a typedef, such as: template<class T> struct A {}; template<class T>
7
by: CoolPint | last post by:
While I was testing my understanding of Functioin Template features by playing with simple function templates, I got into a problem which I cannot understand. I would be very grateful if someone...
31
by: nikola | last post by:
Hi all, I was working with a simple function template to find the min of two values. But since I would like the two values to be different (type) I dont know what kind of value (type) it will...
3
by: CoolPint | last post by:
After upgrading to gcc 3.4.2 from gcc 3.2.3, I got compiler errors that I could not figure out. After reading other postings, I learned that my coding was not compliant to the standard in the first...
4
by: Imre | last post by:
Why is the function template a better match for the call in the following code? And how could I write a version of F() that should be called if the argument is a pointer to a type that is...
2
by: Hartmut Sbosny | last post by:
Hello NG, I have a question. I have a header file with a function template and a fully specialized version of it, for instance //======== File "templ.hpp" ======== #include <iostream> // the...
2
by: Michael Stembera | last post by:
Here is a very simple piece of code to repro this bug. template<typename T, int N> inline bool foo( void ) { return true; } template<typename T> inline bool foo<T, 1>( void ) { return...
4
by: Dan Krantz | last post by:
I have the following template to ensure that a given number (val) falls into a range (between vmin & vmax): template<typename T> T ForceNumericRange( const T& val, const T& vmin, const T& vmax)...
7
by: mathieu | last post by:
Hi there, I know this is not possible in c++. So my question, how should I rewrite the following piece of code (without using a dummy class which template parameter could be use for partial...
7
by: sheffmail | last post by:
I have the following code: template <class T> struct MyS { }; template<class T> inline const T& function(const std::locale& loc) {
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.