向量<int>&的C++默认参数?

Posted

技术标签:

【中文标题】向量<int>&的C++默认参数?【英文标题】:C++ Default argument for vector<int>&? 【发布时间】:2011-03-10 00:05:05 【问题描述】:

我有一个函数,

void test( vector<int>& vec );

如何设置 vec 的默认参数? 我试过了

void test( vector<int>& vec = vector<int>() );

但是有一个警告“使用了非标准扩展:'默认参数':从 'std::vector<_ty>' 转换为 'std::vector<_ty> &'”

有没有更好的方法来做到这一点?而不是

void test() 
    vector<int> dummy;
    test( dummy );

问候, 投票站

【问题讨论】:

【参考方案1】:

你试过了吗:

void test(const vector<int>& vec = vector<int>());

C++ 不允许将临时对象绑定到非常量引用。

如果您真的需要vector&lt;int&gt;&amp;(而不是const),您可以声明一个静态实例并将其用作默认(因此非临时)值。

static vector<int> DEFAULT_VECTOR;

void test(vector<int>& vec = DEFAULT_VECTOR);

但请注意,因为 DEFAULT_VECTOR 将(可以)被修改并且不会在每次调用时重置!不确定这是否是您真正想要的。


感谢stinky472,这是一个线程安全的替代方案:

与其提供默认值,不如使用调用另一个版本的零参数版本重载 test()

void test()

  vector<int> vec;
  test(vec);

【讨论】:

+1 但我认为应该指出,如果要修改此“DEFAULT_VECTOR”,“测试”通常不是线程安全的。这可能很乏味,但我强烈建议为这种需求编写两个函数(一个可以重用另一个): void test() vector temp;测试(温度); 附带说明,如果您可以在后者上使用某种方法来返回对自身的此类引用,则有一种获取临时引用的方法......例如operator=。所以,void test(vector&lt;int&gt;&amp; vec = vector&lt;int&gt;().operator=(vector&lt;int&gt;())); 应该可以工作(临时的生命周期在这里不受影响,并且足以处理呼叫)。但请不要这样做:) 感谢您的回答。但我不明白为什么 DEFAULT_VECTOR 应该是静态的。你能解释一下吗?【参考方案2】:

我发现非const 引用参数具有默认值是有问题的。这是什么意思?

通常,采用非const 引用的函数意味着“我可能会更改参数”。如果参数是可选,为什么不传递(非const)指针?这样,当调用者不想传递参数时,他们可以传递NULL。 (有关如何传递函数参数的更多信息,请参阅 here。)

编辑:嗯,当然,还有重载。只需添加另一个不接受此参数的重载。

【讨论】:

@DeadMG:你是指我损坏的语法子系统吗? 我会这样做吗?【参考方案3】:

我知道这个问题是在 2010 年提出的,但对于 C++11,您可以这样做:

void test( vector<int>& vec = ) 
      // Awesome code here

正如this answer 中指出的那样。

【讨论】:

这与问题中的void test( vector&lt;int&gt;&amp; vec = vector&lt;int&gt;() ); 具有相同的含义,由于尝试将临时绑定到非常量引用,这是非法的。在您链接到的答案中,它不是参考。【参考方案4】:

我们无法初始化对临时对象的可变引用。只有 const 引用允许这样做。你所追求的很可能是这样的:

void test( const vector<int>& vec = vector<int>() );

除了避免未定义的行为之外,这在逻辑上和从 const 正确性的角度来看是最有意义的。如果您希望“测试”修改传递给它的原始向量,您将无法明智地提供默认值。因此很明显,您在此处使用 'vec' 是出于只读目的,因此应将其设为 const 引用。

【讨论】:

您不能直接初始化对临时对象的可变引用,期间。临时不会绑定到对非常量的引用 - 如果您尝试这样做,它不是 U.B.,它是格式错误的输入(即编译器错误)。 VC++ 允许您这样做,但正确地指出它是一种语言扩展。 @Pavel 好点!我见过允许这种行为的讨厌的编译器,比如 MSVC 和 CodeWarrior 的过去版本,其中代码构建但崩溃了。为了准确起见,我将相应地修改帖子。感谢您指出。【参考方案5】:

您可以只传递一个指向向量的指针并将其初始化为 NULL

void test( vector<int>* vec = NULL );

【讨论】:

【参考方案6】:

我知道这个问题是在大约 10 年前提出的。但是对于现在找到解决方案的任何人,我已经为您准备好了。我基本上有三种不同的方法:

void test(vector<int>vec = vector<int>(10, 0)//definition

如果默认向量具有给定大小和公共初始化器值,则可以使用它。

void test(vector<int>vec = vector<int>1, 2, 3, 4)//definition

如果默认向量具有给定大小和不同的初始化器值,则可以使用它。

另一种方法是将全局矢量对象定义为:

vector<int> globalvector;

(已初始化或未初始化)并将此对象作为默认值传递为

void test(vector<int>vec = globalvector)//definition

最后一个的一个重要好处是它可以更好地控制默认值本身,因为函数可用于在控制到达test() 函数之前将值分配给此globalvector。另一个好处是(据我所知),如果函数涉及通过引用传递,它的工作原理和以下一样:

void test(vector<int>& vec = globalvector)//definition

不同于前两者。

【讨论】:

以上是关于向量<int>&的C++默认参数?的主要内容,如果未能解决你的问题,请参考以下文章

使用 swig 类型映射从 c++ 方法返回向量<pair<int,int>> & 到 python 元组列表

C++ 中的向量存储

C++:默认参数和向量

从 C++ 向量中提取引用

如何在 C++ 中将输入正确读入 2D 向量 vector<vector<int>>

C++中向量的初始容量