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]
Function "Overload" Question
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?...
[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.
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:
Then you just need to put your control logic in the first function, and be able to make calls like this:
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.
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?
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
#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]
[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]
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
Popular Topics
Advertisement