Click here to Skip to main content
Click here to Skip to main content

Function Overload by Return

By , 5 Apr 2007
 

Introduction

This code shows one way to use the C++ overload rule using the function return type instead of its signature. Of course, nothing is changed in the language, and the result just looks like a return type overload.

Background

The function overload, in other words, reusing an existent function name but with different parameters, is something more or less known by the C++, Java and .NET community. As a sine qua non condition, we know that the overloaded function signature must be always different from its homonyms colleagues. The code below illustrates this:

GUID guid;
wstring guidS;

CreateNewGUID(guidS); // calls void CreateNewGUID(wstring&)
CreateNewGUID(guid);  // calls void CreateNewGUID(GUID&) (the compiler knows that)

It's a pretty common way to accept different input formats. But what about the output? How to extract different information or the same information in different format using the overload feature (e.g. the above example) without passing the result variable as a output argument? Giving ourselves some imagination and thinking how a valid construction would be, we can think of something like this:

GUID guid;
wstring guidS;

guidS = CreateNewGUID(); // calls wstring CreateNewGUID()
guid = CreateNewGUID();  // calls GUID CreateNewGUID() (the compiler knows that?)

Opening again our old and hurt C++ theories book, we can see the above code DOES NOT work. Or, at least, should not be. Just defining a couple of functions like that causes the following error:

error C2556: 'GUID CreateNewGUID(void)' : overloaded function differs 
	only by return type from 'std::wstring CreateNewGUID(void)'

That's right. Well, the error is right. The return type is not a function property that identifies it uniquely. Only the signature can do that (the parameters received by the function). AFAIK, this "limitation" is hack proof. Anyway, nothing disallows us to use another feature besides ordinary functions:

struct CreateNewGUID
{
   // what is supposed to be here?
};

We got it! Now we can "call" our "function" creating a new instance of the struct and attributing the "return" to a wstring or to our GUID struct:

guidS = CreateNewGUID(); 	// instantiates a CreateNewGUID
guid = CreateNewGUID(); 	// instantiates a CreateNewGUID. 
			// The difference is in the "return"

Using the Code

Since we create a new type, and knowing that this new type is different from the already known wstring and GUID types, we should simply convert our new type into every desirable return type:

struct CreateNewGUID
{
   operator wstring () { ... } 	// the conversion is the "function call"

   operator GUID () { ... } 	// as there's a couple of conversions... 
				// over... underload!
};

This concludes our somewhat odd solution to overload a "function" by the return type:

// instantiates a CreateNewGUID e calls CreateNewGUID::operator wstring()
guidS = CreateNewGUID();

// instantiates a CreateNewGUID e calls CreateNewGUID::operator GUID()
guid = CreateNewGUID();

There's the entire source.

/** @file underload.cpp
@brief A way to make overload using just the return type.
@author Wanderley Caloni
*/
#include <windows.h>
#include <objbase.h>

#include <iostream />
#include <string>

using namespace std;

struct CreateNewGUID
{
   operator wstring () // the first function...
   {
      GUID guid = operator GUID();
      OLECHAR buf[40] = { };
      ::StringFromGUID2(guid, buf, sizeof(buf));
      return wstring(buf);
   }

   operator GUID () // ... and its "underload"
   {
      GUID guid = { };
      ::CoCreateGuid(&guid);
      return guid;
   }
};

Points of Interest

This code was developed a long time ago as an answer to a friend's doubt. I learnt while coding that C++ is even more powerful than we think it is. In one form or another, we can always get what we want.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Wanderley Caloni
Web Developer Caloni Tecnology
Brazil Brazil
Member
Capacitation
Ten years experience in Windows operating systems developing in information security companies;
great team relationship; problem solving using systemic vision, knowledge bases maintenance,
chronograms and people coordination.
 
Technical historic
Software and hardware inventory
Clipboard and PrintScreen protection using windows hooks and global messages manipulation
Driver writing system event log
DeviceIoControl user/kernel communication
Desktop remote control using VNC technique
Remote execution tool PsExec (SysInternals) like
Print control using regex (Boost) and shell hook
Access policies management during user logon/logoff (register and hooks)
Datgabase migration CTree -> SQL (OLE classes)
Windows authentication using custom GINA and DCOM; Credential Provider (Vista)
CTree database synchronism using custom DCOM service
Bootable Linux CD with bash scripts and disk cryptography tools using C language
Hard disk encryption and PenDrive (USB) storage control
Blue Screen analysis using memory dumps and WinDbg live (Gflags)
System account execution using custom COM service
MBR (Master Boot Record) customization library
Blowfish/SHA-1 encryption library using C++ and 16 bits Assembly
Log access driver using shared memory between user and kernel mode
Kernel mode API hook for 9X and NT platforms
16 bits Assembly loader; debugging using debug.com tool
Executable protection using embedded domain authentication recorded inside files resources
Internet Explorer 6/7 and Firefox 1/2 browsing protection using Assembly 32 bits code injection
Code, strings and execution protection library (using Win32 interruptions)
Centralized log generation library using shared memory and global events
Internet Explorer 6/7 BHO (Broser Helper Object) and ActiveX; Mozilla/Firefox XPI plugin
Projects management using Source Safe, Bazaar and Batch (Win) scripts
Kernel mode debugging using SoftIce and WinDbg for NT
etc

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
SuggestionAlternative [modified]memberPascal Damman16 Sep '11 - 2:49 
Though not that experienced in C++, I thought of another way. More or less inspired by the "objects" in C#.
Instead of using a structure, you can use a class. Please see below what I mean (I compiled it, and it works (VS2005)):
Maybe the logic can be put in a private function, so that the different public functions are just for returning the right type.
 
#include <windows.h>
#include <stdio.h>

class Convert {
public:
	int ToInt( char* s) {
		return atoi( s);
		}
 
	LONG ToLong( char* s) {
		return atol( s);
		}
 
	double ToDouble( char* s) {
		return atof( s);
		}
	
	};
 

//--------------------------------------------------------------------
int main( int argc, char* argv[]) {
 
	int i = Convert().ToInt( "1234");
	printf( "int: %u\n", i);
 
	LONG l = Convert().ToLong( "1234");
	printf( "LONG: %u\n", l);
 
	double d = Convert().ToDouble( "1234.5");
	printf( "Double: %#.1f\n", d);
 
	}
Chau chau,
 
Pascalos
modified on Friday, September 16, 2011 9:09 AM

GeneralNice ArticlememberGuimaSun8 May '07 - 3:33 
Very well written and useful article !
{}s
 


 

GeneralRe: Nice ArticlememberWanderley Caloni8 May '07 - 4:25 
Thanks =)
 
--------------------
Wanderley Caloni Jr.
 
http://www.cthings.org

QuestionHow to Create member fcuntions like what u said?membershtarwaterloo16 Apr '07 - 17:46 
How to Create member fcuntions like what u said?
and how to give this functions some parameters,like:
double d = t.CreateUI(1);
int i = t.CreateUI(1);
AnswerRe: How to Create member fcuntions like what u said?memberWanderley Caloni17 Apr '07 - 3:34 
You must follow the article code. In order to the funcion have some parameters is achieved by making one or more constructors receiving these parameters.
 
--------------------
Wanderley Caloni Jr.
 
http://www.cthings.org

GeneralRe: How to Create member fcuntions like what u said?membershtarwaterloo24 Apr '07 - 15:43 
Thanks!
great idea to pass some parameters to the 'functions'!
GeneralRe: How to Create member fcuntions like what u said?membersylvaticus7 Aug '07 - 1:35 
[C++ newbie] And what to make available other classes to the struct without having to pass the "function" a pointer??? Is that possible??
GeneralRe: How to Create member fcuntions like what u said?memberWanderley Caloni7 Aug '07 - 3:43 
I don't see any problems passing a pointer through the "function" constructor, but you can pass a reference if you think is more feasible for your code, or, if you're meaning "pass" as inheritance, you can apply this as well. Let's code:
 

// Example 1: passing a pointer to the "function"
class ClassArg
{
// ...
};
 
struct Function
{
Function(ClassArg* cArg) { ... }
};
 

// Example 2: passing a reference to the "function"
struct Function
{
Function(const ClassArg& cArg) { ... } // obs.: choise between const or not
};
 

// Example 3: inherit the class
class ClassArg
{
protected:
int m_x;
// ...
};
 
struct Function : ClassArg
{
Function()
{
m_x += 10;
}
};

 

I hope I could clarify your doubt.
 
[]s
 
--------------------
Wanderley Caloni Jr.
 
http://www.cthings.org

GeneralThanksmemberneurorebel_6 Apr '07 - 2:33 
Cool article with people coming up with even a nicer idea via discussion ! Thank you all Smile | :)
GeneralRe: ThanksmemberWanderley Caloni6 Apr '07 - 5:38 
Thank you for reading and participating =)
 
--------------------
Wanderley Caloni Jr.
 
http://www.cthings.org

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 6 Apr 2007
Article Copyright 2007 by Wanderley Caloni
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid