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]
8 replies to this topic
Sponsor:
#2 Members - Reputation: 157
Posted 17 June 2012 - 06:33 PM
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.
EDIT: aargh, stupid source tags, why do they cut off angle brackets if I specify a language type?...
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++;
}
}EDIT: aargh, stupid source tags, why do they cut off angle brackets if I specify a language type?...
Edited by BattleMetalChris, 17 June 2012 - 06:50 PM.
#5 Members - Reputation: 629
Posted 18 June 2012 - 02:24 AM
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:
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.
#6 Members - Reputation: 343
Posted 18 June 2012 - 04:10 AM
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
Edited by Eigen, 18 June 2012 - 04:16 AM.
#7 Members - Reputation: 343
Posted 18 June 2012 - 04:36 AM
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






