Void as a function parameter

Started by
11 comments, last by ETFBlade 20 years, 2 months ago
I have a question about syntax. Say you have a function void foo( struct a, int b, int c). Where: struct a{ int z, y;}; And where: void foo ( struct a, int b, int c){ a.z = b; a.y = c; } Now, I want to overload this function''s definition so that it can take either a,b,c, just a and b, just a and c, or just a as parameters. (I.e. foo( a, b, c,)... foo( a, c ).... foo ( a ,b)... ) My question is thus: With creating a declaration for a function that takes two out of three parameters, (i.e. foo( a, ,c)), where you need to be sure that the one int parameter you are using is the the third one so that it can be assigned properly, how would you create it so that the middle parameter of foo takes void. I know syntactically you can''t just enter void as the parameter, but I think there is a way to do it. (i.e. for loops can run without the first parameter defined )
Advertisement
You can''t, but why do you need to do that?

Also, for loops have a special syntax that can''t be entirely emulated in a function.
And the rockets' red glare, the bombs bursting in air,gave proof through the fight that our flag was still there.Oh say, does that star-spangled banner yet waveover the land of the free and the home of the brave?
Grrrr.... lol
I was hoping there was something out there beyond my knowledge that would allow me to do that.

The reason I ask is because the prior problem had been vaguely defined in an assignment. I assumed he meant to only overload the function to include the case where the first two parameters were defined. But the way he worded it, it sounded like either the second or third could be defined, in which case I would need to know that the second parameter being passed is actually meant to be the third parameter, while nothing is passed for the second.
I think i know what you want... You can specify a default parameter if it is not used:

void foo(int a, int b = 0, int c = 0){int mya = a;int myb = b;int myc = c;};


Notice that after b i declared c as 0 as well. you can''t do this:
void foo(int a = 0, int b, int c)  //can''t do this..{};


------------------------------------------VOTE Patrick O'GradyWrite in Presidential CandidateThe Candidate who Cares.
No, default values can''t be in the middle. Once one variable has a default value, all of the ones to the right of it have to, too.

Come to think about it, you can make "void" arguements to functions with macros, I think, but I wouldn''t go there.
And the rockets' red glare, the bombs bursting in air,gave proof through the fight that our flag was still there.Oh say, does that star-spangled banner yet waveover the land of the free and the home of the brave?
Haha. You say don''t go there, but my thirst for knowledge drives me to kkknnnooowww!!! Haha.
I''ve come up with a quick way that would let you define "empty/void" parameters... [won''t work for structs...]
but
it''s (way too) complicated,
is [ugly|bad|rulebreaking|etc] code
creates more work then it saves
there''s probably a better way to do what you want, without being able to have "void" parameters.

Anyways, here it is...
template <class type>class P{private:    bool    _valid;    type    _content;public:    P       (void)                 {_valid=false;}    P       (type input)           {_valid=true;_content=input;}      bool  valid (void)const      {return _valid;};      type  content (void)const    {return _content;};};void function (P<long> a,P<long> b,P<long> c){// Now you can decide what to do     if (a.valid())        //do something usefull with a    else        //ignore this parameter	}void main(void){    // Note parameter a is ''empty/void'', b and c contain values    function (P<long>(),P<long>(1),P<long>(2));}// Disclaimer:// This sourcecode is provided "as is". I take no responsiblity for anything bad that may come of actually using it.// Please direct all flames concerning ''bad coding habits'' to /dev/null ;)


After you''ve marveled at this wonderfull []piece of code longe enough...
Think about this:
Is this really the only solution to your problem?
Isn''t there a better way, without allowing ''void'' parameters, to do what you want?

If you would, for example, state what your function is supposed to be doing, people might be able to point out a better way to do it, without ''void'' parameters?
How do I set my laser printer on stun?
quote:Original post by ETFBlade
struct a{
int z, y;};

And where:
void foo ( struct a, int b, int c){
a.z = b;
a.y = c;
}


Noone else seems to have picked up on the part how the OP wants the function to *initialize the first argument*. This suggests the refactoring:
struct a {  int z, y;  // In C++, structs are the same as classes really, except that  // POD-structs can benefit from special handling sometimes  void foo(int b = 0, int c = 0) : z(b), y(c) {}}// example usesa.foo();a.foo(b);a.foo(b,c); 


Of course, with this, a single argument will always be interpreted as representing b. If you make b and c use different types, you can overload foo by adding another method to the struct:

  // in a  void foo(othertype c) : z(0), y(c) {} 


I don''t know if this can be made to work using typedefs that resolve to the same underlying type. I also don''t know what happens if default arguments allow for ambiguity (e.g. if you specified "othertype c = 0", so that foo() could use either). Probably a compiler error.

If you really need to be able to pick and choose from several arguements to initialize, or non-default parameters to pass in - rethink your design. For only 2 or 3 parameters, filling in the "missing" ones is not particularly burdensome.

If it''s *really* needed though - you could perhaps use a hashtable (one of the STL implementations presumably) as the input argument, and iterate over it, looking at the keys to determine which parameter the value corresponds to. Then assume defaults for everything else. That seriously lacks elegance though.
I don''t think anyone else caught this, but in the OP''s original foo() function, he''s passing the struct by value. It should be corrected to pass by pointer, or by reference.
quote:Original post by Zahlman

struct a {  int z, y;  // In C++, structs are the same as classes really, except that  // POD-structs can benefit from special handling sometimes  void foo(int b = 0, int c = 0) : z(b), y(c) {}}// example usesa.foo();a.foo(b);a.foo(b,c); 




errr what the hell, you can''t do that. Initializer list only works on ctors. That looks like a regular member func to me.

In regards to the OP''s question I think it''s much more straightforward to just use different names for each function. Remember overloading functions can easily be abused and in this particular case it would be much clearer to use something like this instead:

void foo (atype a, int b, int c);void foob(atype a, int b);void fooc(atype a, int c); 


Oh and it doesn''t look like the syntax on the declared struct is used correctly. a is declared as new type but you''re using it as if it''s an actual variable instance in your foo().





--{You fight like a dairy farmer!}

--{You fight like a dairy farmer!}

This topic is closed to new replies.

Advertisement