【问题标题】:Using a struct to pass multiple values使用结构传递多个值
【发布时间】:2013-01-18 08:38:21
【问题描述】:

所以我有一个需要两个字符和两个整数的函数:

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

我想通过传递一个包含四个值的结构来调用它:

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

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

我希望能够这样称呼它:

Value_Holder vh;
need_2xcha_2xint(vh);

当然,我可以编写另一个函数来接受我的自定义结构并适当地处理它,但我想知道是否有办法告诉结构直接输出四个单独的值。这将主要用于与 DirectX 库交互。

我确信这是基本的东西,但我一直在研究 C++ 的许多不同领域,很难记住所有内容。我已经搜索了一段时间的答案,但我不太确定我应该搜索什么。我的谷歌技能让我失望了!

提前致谢。

  • 编辑-

似乎人们对我的问题感到困惑,我将在这里尝试简化它:

有没有办法让一个需要 2 个整数和 2 个字符的函数接受一个保存这些值而不是四个单独值的结构?

我希望这能澄清我的问题。

【问题讨论】:

  • 嗯,你为什么不写need2xcha_2xint(vh.a, vh.b, vh.x, vh.y);?
  • “一种告诉结构直接输出四个单独值的方法”——你是什么意思?我不太明白你的问题。
  • 认为他希望使用 struct 的函数调用与具有 4 个参数的函数 def 一起使用
  • 我认为可以部分回答您的问题:stackoverflow.com/questions/2758937/…
  • 我不想写(vh.a vh.b 等...),因为我可能想传递 100 或 200 个值。我认为 Karthik 是我想要的。对不起,如果我无法清楚地解释自己。我认为我的词汇不正确。

标签: c++ function struct


【解决方案1】:

包装第三方库:

namespace david {

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

}

使用它:

int main() {
    Value_Holder value;

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

编辑

我很确定您可以使用模板和函数指针来封装它。

【讨论】:

  • 谢谢彼得,这似乎最接近我想要的。一旦我吃过东西,我会回来回顾一下。
  • 这正是我想要的。完美!
【解决方案2】:

一种告诉结构直接输出四个单独值的方法

如果您的意思是输出到 std::ostream(例如 std::cout),则为 Value_Holder 添加流式运算符...

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

然后您可以使用例如:

Value_Holder v;
...
std::cout << "whatever " << v << " some more\n";

【讨论】:

  • 这并没有真正回答这个问题。他正在谈论将其传递给第三方库。
  • 感谢您的快速回复,但我不想只输出数据。我希望能够使用函数不会直接接受的单个结构将多个值传递给函数。 - 作为上面的忍者:)
【解决方案3】:

我知道这不是一个很好的决定,你应该避免任何定义,但无论如何,你可以试试这个:

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;
}

当然离自己封装这个函数也不远了。

【讨论】:

  • 这看起来很有趣。我已经接受了彼得的解决方案,但我也会尝试解决这个问题。谢谢你的回答。
  • 我对此进行了测试,并且效果也很好。我猜包装更好,因为我们被建议不要使用一般定义,但很高兴看到替代解决方案。
【解决方案4】:

有没有办法让需要 2 个整数和 2 个字符的函数接受一个保存这些值而不是四个单独值的结构?

不,没有。

您可以使用预处理器尝试不同的技巧,但这是一种错误且死胡同的方式。

为什么不直接使用结构?尽可能多地关注KISS principle

【讨论】:

  • 好答案!我无法使用该结构,因为我正在使用 DirectX 库函数,并且在更改它时我没有任何想法或信心。
【解决方案5】:

需要将多个参数传递给函数会得出需要下层对象的结论。在您的情况下,您创建了结构。

但不要忘记Single Responsibility Principle,这需要考虑类的职责:类应该保持简单明了,而不仅仅是一堆有时不相关的参数。

在你的情况下,我不确定,但是当我看到 (int x, int y) 时,我想知道是 class Point 还是 Vector,或班级规模处于危险之中。如果是这样,我将只封装一对 int x, int y 在有问题的新类中。

对于此类问题,我推荐 Martin Fowler 的“重构:改进现有代码的设计”一书。他列出了修改方法、将代码转换为更清晰、更易于维护、可修改的状态,以及何时/为什么要重构代码。

【讨论】:

  • 谢谢斯蒂芬。我不知道下面的物体是什么,我得研究一下。
  • subjacent:这不是一个正式的 c++ 术语 :-) 它只是意味着:一个正在“寻找”存在的对象,因为它代表了一些在整个代码中隐含的逻辑计算行为。当你把它变成一个对象时:它变得明确。 (在 c++ 关键字意义上明确不是 :-))
【解决方案6】:

我认为 fuchsgeist 提供的答案是最好的方法。如果我理解正确,那么您需要将 4 个参数传递给您的库函数。我希望下面的代码解决了你的问题。

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

希望我正确理解了您的问题。

好的,我在您编辑后收到了您的问题。您可以在此处使用函数重载概念。重载库函数以接受您的结构。这可以解决您的问题吗?

【讨论】:

    猜你喜欢
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多