Function "Overload" Question

Started by
7 comments, last by Ryan_001 11 years, 10 months ago
This is a long shot, but is there any way, in C++, to overload a function such that it takes an arbitrary number of parameters (without explicitly overloading it a thousand times) and can evaluate various control structures and/or output the "parameter number" (ie foo(a, b, c), where "a" is parameter 0, "b" is parameter 1 etc? Obviously each of the arbitrary number of parameters would have to be the same type. An example of my ideal solution...:

[source lang="cpp"]foo(any number of std::strings){
std::string str;
cin >> str;
if (str == any of the input strings){
return parameter_number_of_the_string_it's_equal_to;
} // if
} // foo[/source]
Advertisement
Could you not just pass a reference to a vector of the parameters? This also lets you use templates if you plan on having several versions for different parameter types.

[source]typedef std::vector<std::string> ParamsVec;

int foo(ParamsVec& params)
{
std::string str;
cin >> str;

int count = 0;
for (ParamsVec::iterator it = params.begin(); it != params.end(); ++it)
{
if ((*it) == str) return count;
count++;
}
}[/source]



EDIT: aargh, stupid source tags, why do they cut off angle brackets if I specify a language type?...
That works, thanks. I was just wondering if there was actually something like what I described with the arbitrary number of separate parameters, as it would cut out the step of creating the vector. Otherwise I can live with that.
If using a C++11 compiler you can use variadic templates.
I'd just like to add that you don't necessarily need to use the same type for your parameters. You can use a variant type to wrap different parameter types and pass them in a vector to your function. Look at Boost.Any for a very simple, elegant and fairly efficient variant type. Definitely faster than doing things like converting strings to integers or floats.

You can also roll out a bunch of template functions to help automate the process of creating the vectors to make the code easier to use. i.e:


void foo( const std::vector<boost::any>& params )
{
//iterate params and work!
}

template<typename T1>
void foo( T1 p1 )
{
std::vector<boost::any> params;
params.push_back(p1);
foo(params);
}

template<typename T1 p1, typename T2 p2>
{
std::vector<boost::any> params;
params.push_back(p1);
params.push_back(p2);
foo(params);
}
///etc up to Tn/Pn



Then you just need to put your control logic in the first function, and be able to make calls like this:

foo( 1, 0.5f, "whatever", new SomeUserType() );

You could also use some C++ macros/metaprogramming to generate as many template functions as you need without having to create them all explicitly.

Not quite as handy as variadic templates, but should work on any(most?) C++03 compiler.
Variable argument list?


#include <stdarg.h>

void vaFunc(int stringCount, ...)
{
va_list vl;
va_start(vl, stringCount);

for(int i = 0; i < stringCount; ++i)
{
printf("arg%d = %s\n", i, va_arg(vl, char *));
}

va_end(vl);
}

vaFunc(2, "hello", "world");




This function expects all arguments to be char *, but if you want them to be to be of different type, you need to differate between them somehow. Take a look at this for an idea: http://msdn.microsof...9(v=vs.80).aspx
Scrap my previous post, I misread the topic. What you actually need, is this:



int countArguments(const char * arg, ...)
{
va_list vl;
va_start(vl, arg);

printf("arg0 = %s\n", arg);

int i = 1;
while((arg = va_arg(vl, const char *)) != NULL)
{
printf("arg%d = %s\n", i, arg);
i++;
}

va_end( vl );

return i;
}

printf("Argument count: %d\n", countArguments("Hello", "world", NULL); // Pass 0 or NULL as the last parameters, to detect the end of argument list
[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

[background=rgb(250, 251, 252)]"Basically whenever you invoke the dread ellipses construct you leave the happy world of type safety." — SiCrane [/background]

[/font]

[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

[background=rgb(250, 251, 252)]:)[/background]

[/font]

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
There's always the option of using macros to define how ever many versions of the function you want. Its very messy but it does work. I suggest using the boost pre-processor library to help.

This topic is closed to new replies.

Advertisement