Reputation: 10817
In Javascript or ActionScript it's possible to pass an object to a function or a constructor.
myfunction({myParam:1, myOtherParam:"hello"});
It is very useful when you have a lot of parameters to pass, IMO it makes using functions easier than using the classic approach.
myFunction(1,"hello");
Is there something similar in C++?
TIA
Upvotes: 0
Views: 248
Reputation: 4962
boost parameter http://www.boost.org/doc/libs/release/libs/parameter/ do exactly what you want.
From its abstract:
Use this library to write functions and class templates that can accept arguments by name
Small example:
// include boost parameter
#include <boost/parameter/keyword.hpp>
namespace parameter = boost::parameter;
// first declare named parameters
BOOST_PARAMETER_NAME(a) // Note: no semicolon
BOOST_PARAMETER_NAME(b)
// then declare your function
BOOST_PARAMETER_FUNCTION(
(int), // 1. parenthesized return type
my_function, // 2. name of the function
tag, // 3. namespace of tag types (don't change!)
(required (a, int) ) // 4. one required parameter of type int
(optional // and an optional parameters, with default value
(b, int, 0)
)
)
{
return a + b;
}
// then you can call it with no named parameters
int result = my_function(1, 2);
// or with named parameters
int result = my_function(_a=1, _b=2);
// also with optional parameters omitted
int result = my_function(_a=3);
Upvotes: 4
Reputation: 34628
You can do the following, which supports default values to a limited amount (limited by the template system of C++). You will need to compile this with the newest standard (C++11)
// used to skip arguments and default to the previously specified value
struct UseDefault {
// empty intentionally!
};
// using this is optional, and only required if you want to provide default values by the CALLED function
template <typename T, T def> struct Default {
T value;
operator T() {
return value;
}
Default(T value) : value(value) {}
Default(UseDefault ignore) : value(def) {(void)ignore;}
};
// using tuple, you can bundle any number of parameters to one
int myFunc(std::tuple<Default<int,7>,Default<char,'x'>,std::string> parameters) {
std::cout << std::get<0>(parameters) << ", " << std::get<1>(parameters) << std::endl;
return 0;
}
You can then invoke myFunc
like this:
func(std::make_tuple(6,UseDefault(),"hi"));
Note however, that there are some limitation to the template parameter types, for instance, you cannot pass strings (or char*
s for that matter) as template parameters. However, if you only need reasonable basic default values, this could work.
Of course if you drop your requirement to specify default values, you can simply use the std::tuple
without my Default
type.
Upvotes: 0
Reputation: 8401
You can use the "named parameter idiom": http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.20
Which would make your call look like:
f(1).myOtherParam("Hello")
See here for a comparison with Boost parameter.
Upvotes: 1
Reputation: 6797
Not at the language level, but:
It is very useful when you have a lot of parameters to pass, IMO it makes using functions easier than using the classic approach.
You should really consider cutting down on your parameters if you can. Often this can be achieved by using aggregates:
Example:
draw_rectangle(x1, y1, x2, y2, r, g, b, a)
Could be reduced to:
draw_rectangle(p1, p2, color)
Or even further:
draw_rectangle(rect, color)
The temptation for named parameters should be mitigated considerably if you do this.
You can also use alternative approaches like Boost Parameter which, through a lot of template magic, accomplishes something like this. However, it requires you turn all your functions using this technique into templates written in a very precise way, and it's a very bulky and heavy-handed attempt to force the language to do something it wasn't designed to do if you ask me.
Upvotes: 0
Reputation: 13213
Use structs or classes to group your data.
If you're looking for a way to pass key value pairs, use STL maps
Upvotes: 0
Reputation: 81684
No, not really. There is a map
class in the standard library, and of course you could write a function that accepted a map
full of named values as input, but there's nothing that exists directly as a language feature equivalent to what you've shown.
As several other posters have pointed out, of course you can define a class to hold all the data values, but this just pushes the ordered parameter list from the function to the constructor of that object, so it buys you nothing at all.
Upvotes: 0
Reputation: 98469
Yes.
In C++, an object is an instance of a class. You could create a class holding all the possible arguments, instantiate it and fill it with your particular values, and then pass that instance to the function.
You cannot just pass an arbitrary object instead of the function's arguments, because C++ doesn't have named arguments - only the position matters, and the position within some kind of hash structure is lost. So you can't say foo(y=3)
when you have a function foo(int x, int y)
because the names x
and y
only have meaning within the function - not to its callers.
Upvotes: 0
Reputation: 46607
One could use structures:
struct foo {
int a,b,c;
float f;
}
Sadly, you need to define them somewhere and the receiving function needs to accept them, you can't just make them up in-place.
At the end of the day, there's no language tool in C++ that could mimic the JavaScript 'idiom'. Such stuff lies in the nature of a dynamic language, which C++ is not.
Upvotes: 0