4

这是一个简单的问题:

如果我必须调用这样的方法,例如:

void getBounds(float &xmin, float &ymin, float &zmin,
             float &xmax, float &ymax, float &zmax)

如果我只需要存储在 xmax 中的信息,那么调用该方法的正确方法是什么?我不想创建我不会使用的变量。

有没有办法做到这一点?假设做我想做的事情的错误方式是这样的:

float xmax;
getBounds(nullptr, nullptr, nullptr, xmax, nullptr, nullptr);

现在我正在使用虚拟垃圾变量,但也许还有另一种方法。

提前致谢。

编辑:对不起,我忘了提到我无法编辑该方法,来自第三方库。

4

6 回答 6

2

能不能修改getBounds?如果可以,并且计算每个值的成本很高,则可能值得将其更改为传递指针,并且仅在指针为非空时才进行相关计算。否则,您需要将一个左值(变量)传递给每个。从理论上讲,如果你将同一个变量传递给多个参数,你可能会在函数中得到未定义的行为(比如因为函数以类似的行开头xmin = ymin = 0.0;)。

最后,除非每个值的计算成本很高,并且如果函数获得空指针就跳过它,否则创建和传递额外的变量不太可能对性能产生任何影响。

于 2013-06-21T08:18:01.780 回答
1

就像是:

float dummy;
float xmax;

getBounds(dummy, dummy, dummy, xmax, dummy, dummy);

这只会在堆栈上创建一个变量,从而节省空间 - 创建更多变量不会有任何副作用,除了每个占用另外 4 个字节[假设“正常”大小的浮点数,标准没有指定浮点数的确切大小] - 创建一个或五个(或一百个)基于堆栈的未初始化变量需要相同的时间。

使用指针将允许您传入 a nullptr,但是,这也会在 中添加额外的检查getBounds,所以

void getBounds(....)
{
    xmin = the_getXmin_function();
    ...
}

变成:

void getBounds(....)
{
    if (xmin != nullptr)
        *xmin = the_getXmin_function();
    ...
}

假设the_getXmin_function是微不足道的,这会减慢代码的速度。如果函数很复杂,那么有一个 if 和“我不想要这个”选项将有助于提高性能。

于 2013-06-21T08:10:17.587 回答
0

如果您可以重写 getBounds 并且可以使用 C++11,请考虑使用 tuple、tie 和 ignore:

std::tuple<float, float, float, float, float, float> getBounds()
{
  std::tuple<float, float, float, float, float, float> r;
  :
  std::get<3>(r) = ...;
  :
  return(r);
}
:
float xmax;
std::tie(std::ignore, std::ignore, std::ignore, xmax, std::ignore, std::ignore> = getBounds();

- 编辑 -

由于您无法更改它,因此您可能会超载它。无参数版本只会包裹原始版本,将所有内容打包在一个元组中并返回它。

于 2013-06-21T12:42:16.190 回答
0

如果函数正在等待引用,则不能发送 nullptr

但是,如果您将函数签名更改为指针,则可以执行以下操作:void getBounds(float *xmax, float *xmin = nullptr, float *ymin = nullptr, float *zmin = nullptr, float *ymax = nullptr, float *zmax = nullptr) { }

并调用它:getBounds( &xmax);但是如果变量为 nullptr 或否,您必须检查您的函数

但正如评论中所说,它只适用于一种情况

于 2013-06-21T08:15:14.880 回答
0

向 Mats Petersson 致谢:您不能传递 nullptr,因为该函数需要引用。

如果函数没有附加担保,那么您应该创建临时变量并将它们全部传递。传递相同的变量是不安全的;如果它用于内部计算。

即使该函数使用传递的相同变量,也不能保证有人不会以导致您的代码中断的方式更改该函数的实现。将来您可能会向讨厌的错误敞开心扉。

于 2013-06-21T08:08:21.540 回答
0

如果您编写了该方法,只需将函数的签名更改为

void getBounds( float*, float*, float*, float*, float*, float* )

这样你就可以通过nullptrs如果你想忽略一个参数。否则你可能想写一个包装函数。

void getBounds( float*a, float*b, float*c, float*d, float*e, float*f )
{
    float dummy;
    getBounds( 
        a ? *a : dummy, 
        b ? *b : dummy, 
        c ? *c : dummy, 
        d ? *d : dummy, 
        e ? *e : dummy, 
        f ? *f : dummy );
}

如果您的情况不经常发生,那么另一种处理方法可能是写

float xmax; // in outer scope
{
    float dummy; // in inner scope. Will be thrown away afterwards
    getBounds( dummy, dummy, dummy, xmax, dummy, dummy );
}

所以你不会乱扔你的范围。

我更喜欢第一个变体。

于 2013-06-21T08:16:22.547 回答