2

我一直在尝试通过引用将 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&”类型参数的默认参数具有“std::vector”类型</p>

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

4

4 回答 4

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,这是非标准行为。海湾合作委员会是正确的。

于 2012-11-06T10:20:53.370 回答
1

You can do the following:

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

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

then you do not have to change the signature of your function. But you have to define the variable empty_vec instead. I put it in an unnamed namespace to make it invisible from outside this translation unit. But the drawback is (as LightnessRacesinOrbit noted below) that within this translation unit the value of empty_vec can be changed, which might break your function.

于 2012-11-06T10:32:57.933 回答
0

您不能将临时对象作为非常量左值引用传递!添加 const 限定符或删除默认参数。

于 2012-11-06T10:21:43.460 回答
-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));
}
于 2015-08-29T23:15:29.770 回答