1

So I have a function that requires two characters and two ints:

void need_2xcha_2xint(char a, char b, int x, int y)
{
  cout << "Working! a: " << a << ", b: " << b << ", x : " << x << ", y: " << y << ".\n";
}

I would like to call it by passing a single struct that contains the four values:

struct Value_Holder
{
char a;
char b;
int x;
int y;

Value_Holder()
    : a('g'), b('h'), x(3), y(5)
  {
  }
};

I want to be able to call it as follows :

Value_Holder vh;
need_2xcha_2xint(vh);

Of course I could write another function that accepts my custom structure and deals with it appropriate, but I was wondering if there's a way to tell the struct to output four seperate values directly. This will mainly be used for interacting with DirectX libraries.

I'm sure this is basic stuff, but I've been working on so many different areas of c++ it's hard to remember everything. I've searched for the answer for a while now, but I'm not quite sure what I should be searching for. My google skills fail me!

Thanks in advance.

  • EDIT -

As it seems people are confused by my qustions I'll try and simplify it here:

Is there a way for a function that requires 2 ints and 2 chars to accept a single structure holding these values instead of four seperate values?

I hope that clarifies my question.

David
  • 1,050
  • 1
  • 16
  • 31
  • Hm, why don't you write need2xcha_2xint(vh.a, vh.b, vh.x, vh.y);? – x squared Jan 18 '13 at 08:40
  • 1
    "a way to tell the struct to output four seperate values directly" -- what do you mean? I don't really understand your question. – Dariusz Jan 18 '13 at 08:41
  • Think he wants the function call with the struct to work with the function def with the 4 parameters – Karthik T Jan 18 '13 at 08:42
  • I think provides partial answer to your question: http://stackoverflow.com/questions/2758937/printing-values-of-all-fields-in-c-structure – İsmet Alkan Jan 18 '13 at 08:43
  • I don't want to write (vh.a vh.b etc...) because I may want to pass 100 or 200 values. I think Karthik is on to what I want. Sorry if I'm unable to explain myself clearly. I don't think I have the right vocabulary. – David Jan 18 '13 at 08:51
  • Just like to say thanks to everyone for their comments, I learnt a lot from this. – David Jan 18 '13 at 11:30

6 Answers6

3

Wrap the third party library:

namespace david {

void need_2xcha_2xint(const Value_Holder& value) {
    ::need_2xcha_2xint(value.a, value.b, value.x, value.y);
}

}

Using it:

int main() {
    Value_Holder value;

    using david::need_2xcha_2xint;
    need_2xcha_2xint(value);
    return 0;
}

edit

I'm pretty sure you could encapsulate this using templates and function pointers.

Peter Wood
  • 23,859
  • 5
  • 60
  • 99
1

a way to tell the struct to output four seperate values directly

If you mean output as in to a std::ostream (e.g. std::cout), then add a streaming operator for Value_Holder...

std::ostream& operator<<(std::ostream& os, const Value_Holder& v)
{
    return os << "{ a " << v.a << ", b " << b.b << ", x " << x << ", y " << y << " }";
}

Then you can print it succinctly using e.g.:

Value_Holder v;
...
std::cout << "whatever " << v << " some more\n";
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • That doesnt really answer the question though. He's talking about passing it to a third party library. – nishantjr Jan 18 '13 at 08:46
  • Thanks for your quick response, however I don't want to just output the data. I want to be able to pass multiple values into a function using a single structure that the function will not accept directly. - as ninjad above :) – David Jan 18 '13 at 08:48
1

I think the answer provided by fuchsgeist is the best way to do it. If I am to understand correct then you need to pass 4 params to your library function. I hope below code solved your problem.

Value_Holder vh;
need_2xcha_2xint(vh.a,vh.b,vh.x,vh.y);

I Hope I understood your problem correctly.

Ok I got your question after your Edit. You can use function overloading concept here. Overload the library function to accept your structure.Will that be a solution to your problem?

spanky
  • 133
  • 1
  • 3
  • 11
1

I know that this is not very good decision, and you should avoid any defines, but anyway, you can try this:

void f(int i, char c)
{
    std::cout << i << " : " << c;
}

struct s
{
    int i;
    char c;
};

#define S_CALL(f, s) (f(s.i, s.c))

int main(int argc, char* argv[])
{
    s param;
    param.i = 1;
    param.c = 'a';

    f(param.i, param.c);
    S_CALL(f, param);

    return 0;
}

Of course it's not far from wrapping this function in your own.

acrilige
  • 2,436
  • 20
  • 30
  • This looks interesting. I've accepted Peter's solution, but I'm going to have a play around with this too. Thank you for your answer. – David Jan 18 '13 at 11:31
  • I tested this and this also works well. I guess the wrapper is better as we are advised not to use define in general, but good to see alternate solutions. – David Jan 18 '13 at 12:29
1

Is there a way for a function that requires 2 ints and 2 chars to accept a single structure holding these values instead of four seperate values?

No, there isn't.

You could try different tricks with preprocessor, but it's a wrong and dead end way.

Why don't you just use the structure? Follow the KISS principle as often as you can.

Wacek
  • 4,326
  • 2
  • 19
  • 28
  • Good answer! I can't use the structure as I'm using DirectX library functions, and I have no idea or confidence when it comes to altering it. – David Jan 18 '13 at 10:41
1

The needing to pass several parameters to a function leads to the conclusion that a subjacent object is needed. In your case you created your struct.

But don't forget the Single Responsibility Principle, which requires to think about the responsibilities of your classes: a classes should remain simple and clear, and not just a mess of sometimes unrelated parameters.

In your case, I'm am not sure, but when ever I see (int x, int y), I wonder if a class Point or Vector, or class Size is at stake. If so I would encapsulate only the pair int x, int y in the new class in question.

For such questions, I recommend the Book "Refactoring: Improving the Design of Existing Code" by Martin Fowler. He list the ways to modify, the code into a cleaner more maintainable, modifiable sate, and when/why to refactor the code.

Stephane Rolland
  • 38,876
  • 35
  • 121
  • 169
  • Thanks Stephane. I have no idea what a subjacent object is, I'll have to look into this. – David Jan 18 '13 at 10:45
  • subjacent: it's not a formal c++ term :-) it just means: an object that is "looking for" existing, because it respresents some logical computatiob behaviour that is implicit in the code throughout. When you make it an object: it becomes explicit. ( explicit not in the c++ keyword sense :-) ) – Stephane Rolland Jan 18 '13 at 11:28