返回语句与接受写入的指针

时间:2013-01-22 18:19:17

标签: c++ function return

  

可能重复:
  In C++, is it still bad practice to return a vector from a function?

在表现方面,当需要返回更重的'来自函数的std::vectorstd::string对象,建议使用此表单

void func(std::vector<int> *dest)
{
}

而不是这种形式:

std::vector<int> func()
{
    std::vector<int> arr;
    // ...
    return arr;
}

我假设第一种形式应该更快,但同时我经常看到第二种形式,Qt API通常会返回一个QString,可能是因为它很多更方便或直观易用。

此外,我想知道是否有编译器优化可以在使用return语句时删除不必要的对象复制。


修改

今天仍然使用的任何热门编译器哪些不执行答案中提到的优化?

4 个答案:

答案 0 :(得分:7)

  

建议使用[按指针传递]而不是[按值返回]?

A modern C++ compiler performs named return value optimisation (NRVO)这实际上意味着编译器可以在此处可靠地删除副本。没有复制。

请注意,这与您使用的C ++版本无关:C ++ 03和C ++ 11一样。在C ++ 11中唯一改变的是,当没有可以执行复制省略时,该语言使库更容易移出一个值(如此处所发生的)高效

对于返回值,通常可以执行复制省略 - 在其他情况下更为相关(例如,按值传递参数)。但也有例外;以下代码不能使用命名返回值优化。它可以使用C ++ 11移动:

std::string foo() {
    std::string one = "Foo";
    std::string two = "Bar";

    if (rand() % 2 == 0)
        return one;
    else
        return two;
}

原因是现在两个代码路径返回不同的命名对象;这可以防止NRVO。

答案 1 :(得分:3)

按价值返回:

std::vector<int> func();

C ++允许复制省略用于这样的情况,除此之外,新的C ++定义了移动语义以使这些操作变得便宜。编译器通常很好地实现了这一点(使用copy elision,您的本地arr实际上将最终构建在收件人调用站点变量中。这种情况也称为“返回值优化”。)

答案 2 :(得分:2)

允许RVO和NRVO的规则出现在ARM(1990)中, 所以如果任何编译器没有实现它们会很奇怪。

更重要的是,使用输出参数(指针或 对非const的引用非常笨拙。不要这样做, 直到剖析器说你真的有时间问题 因为复制了返回值。在这一点上, 过载函数,按照以下方式:

void func( std::vector<int>& dest )
{
    //  ...
}

std::vector<int> func()
{
    std::vector<int> results;
    func( results );
    return results;
}

然后尝试两者,在探查器说你的位置 有问题,并选择解决问题的那个(如果 它有所不同。)

我实际上不得不这样做一次,但那是某个时候 1991年或1992年。从那以后,我没有必要这样做 几年来,我一直在努力做一些漂亮的表现 关键的东西;我们仍会定期返回std::vector或我们的 在内部Matrix课程。没有C ++ 11的优点, 因为并非所有目标编译器都支持它。

答案 3 :(得分:1)

std::vector<int> func();

使用C ++ 11,上面应该是你的功能。函数返回时,本地std::vector对象将移动。如果可能,编译器可以省略 move

总之,不用担心。按价值返回。