修改向量元素(按值,按引用)函数C++

16

我有一个函数,在这个函数中,我必须修改一个向量的值。 在C++中,将向量作为返回值是一种好的实践吗?

Function 1:

vector<string> RemoveSpecialCharacters(vector<string> words)
{
    for (vector<string>::iterator it=words.begin(); it!=words.end(); )
    {
        if(CheckLength(*it) == false)
        {
            it = words.erase(it);
        }
        else{
            ++it;
        }
    }//end for

    return words;
}

功能 2:

void RemoveSpecialCharacters(vector<string> & words)
{
    for (vector<string>::iterator it=words.begin(); it!=words.end(); )
    {
        if(CheckLength(*it) == false)
        {
            it = words.erase(it);
        }
        else{
            ++it;
        }
    }//end for
}

4
这些例子做了不同的事情。一个修改向量,另一个返回不同的向量。那么你实际上需要哪种功能? - juanchopanza
我一直觉得很奇怪的是,复制省略排除了函数参数... - Kerrek SB
1
函数1最终更加灵活。你可以使用v = f(v)来获得函数2的行为,但你也可以使用v = f(g()) - Kerrek SB
1
@juanchopanza 我实际上想要修改向量的值。正如您所看到的,我正在删除具有特定长度的元素。 - Hani Goc
1
第二个版本做了你想要的事情,第一个版本没有。 - juanchopanza
显示剩余3条评论
7个回答

6

你的两个函数有两种不同的用途。

  • 函数1:类似于remove_copy,它不会修改现有的容器;它会复制一个并对其进行修改。

  • 函数2:类似于remove,它会修改现有的容器。


对于函数1,通常你会将返回值分配给另一个向量,因此会创建另一个副本。 - fchen
1
@fchen,任何现代的C++编译器都可以有效地消除这种复制,语言也在不断变化以支持这一点。对于C++11,作者应该写成return std::move(words); - Slava

3

这有些主观。个人而言,我更喜欢后者,因为它不会强制将向量复制到调用者(但是如果他们选择这样做,调用者仍然可以复制)。


2
在这种情况下,我会选择通过引用传递,不是因为它是C++的惯例或不是,而是因为它实际上更有意义(函数按其名称对向量应用修改)。似乎没有实际需要从函数返回数据。
但这也取决于函数的目的。如果您总是希望以以下方式使用它:
vec = bow.RemoveSpecialCharacters(vec);

那么绝对首选是第一种选择。否则,第二种选择似乎更加合适。(根据函数名称的判断,第一种选择在我看来更加合适)。

就性能而言,在现代 C++11 中,第一种解决方案将会慢一些,但影响可以忽略不计。


1

选择第二个选项,修改作为参数传递的向量。

顺便提一下:有些编程实践建议通过指针传递可能被更改的参数(这样开发人员一眼就能清楚地看到函数可能会更改该参数)。


我认为在这里使用指针是完全不必要的。引用同样清晰,并且甚至可能是聪明编译器的优化提示。 - user267885
@Claudio:那更像是C语言传统风格。在C++风格中,您可以通过写const&来表示您不会改变参数。 - MSalters

1
最佳实践是通过引用传递向量。
在函数内部编辑它,您不必将其返回(实际上您分配了不需要的新内存空间)。
如果通过引用传递它,成本会更小,向量也会在函数范围之外被编辑。

0

实际上,如果所谓的良好实践是指在C++库中如何完成,则两者都不是C++的良好实践。您基本上重新实现了std::remove_copy_ifstd::remove_if的功能,因此良好的实践是实现函数(或使用现有函数),这些函数按范围而非容器工作,无论是按值还是按引用。

同样,这取决于您如何定义术语good practice


0
第一个函数将返回向量的副本,所以它会比第二个函数慢。你应该使用第二个函数。

这取决于实际需求。如果需要复制,两个函数执行的效果差不多。 - Spook

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接