如何通过引用将std :: vector传递给函数,默认值是C ++中的空std :: vector?

时间:2012-11-06 10:18:24

标签: c++ visual-studio-2010 gcc

我一直在尝试通过引用将std :: vector传递给函数,默认值为空std :: vector。我的函数声明如下:

void function( std::vector<double>& vec=std::vector<double>(0));

我的功能定义是:

void function( std::vector<double>& vec)
{
...
}

但是我的C ++编译器(gcc 4.6)在这里抛出错误,说:

  

错误:'std :: vector&amp;'类型参数的默认参数类型为'std :: vector'

我已经看到这个版本的代码在Microsoft VS 2010编译器上编译得很好。我想知道这是否是gcc和vs2010之间不同c ++标准解释的问题。

4 个答案:

答案 0 :(得分:9)

你做不到。你不能将临时绑定到ref-to-non - const,所以你只能这样做:

void function(const std::vector<double>& vec = std::vector<double>());

在你的情况下,我建议函数重载:

void function(std::vector<double>& vec)
{
    // ...
}

void function()
{
    std::vector<double> v;
    function(v);
}

如果您不喜欢额外的函数调用,那么您运气不好。 :)

我不知道C ++ 11 rvalue refs在这里是否有帮助,如果你有权访问它们。

  

我已经看到这个版本的代码在Microsoft VS 2010编译器上编译得很好。我想知道这是否是gcc和vs2010之间不同c ++标准解释的问题。

MSVS倾向于允许您将临时值绑定到refs-to-non - const,这是非标准行为。海湾合作委员会是正确的。

答案 1 :(得分:1)

您可以执行以下操作:

namespace{
    auto empty_vec = std::vector<double>();
}

void function(std::vector<double>& vec=empty_vec);

然后您不必更改功能的签名。但您必须改为定义变量empty_vec。我将它放在一个未命名的命名空间中,使其从该翻译单元外部不可见。 但缺点是(如下面提到的LightnessRacesinOrbit),在这个翻译单元中,empty_vec的值可以改变,这可能会破坏你的功能。

答案 2 :(得分:0)

您无法将临时对象作为 nonconst 左值引用传递! 添加const限定符或删除默认参数。

答案 3 :(得分:-1)

以下方法清楚地说明了默认值是什么 - 它可以替换为其他默认行为。

static std::vector<double> emptyVectorProvider()
{
    return (std::vector<double>());
}

void function (std::vector<double>&& = emptyVectorProvider ());

void function2 (std::vector<double>&& def = emptyVectorProvider ())
{
    function(std::forward<std::vector<double> > (def));
}