退回标准容器是否会产生容器内容物的副本?
如果我有一个返回 STL 容器的函数,我是否会产生标准容器全部内容的副本?
例如,这个:
void Foo( std::vector< std::string >* string_list );
比这个更好:
std::vector< std::string > Foo();
容器中的东西重要吗?例如,将返回这样的容器:
struct buzz {
int a;
char b;
float c;
}
std::map< int, buzz > Foo();
比这更昂贵的操作:
std::map< int, int > Foo();
谢谢, PaulH
编辑: 这是使用 C++03 的。不幸的是,C++0x 解决方案是不可接受的。
编辑2: 我正在使用 Microsoft Visual Studio 2008 编译器。
If I have a function that returns an STL container am I incurring a copy of the entire contents of the standard container?
e.g. Is this:
void Foo( std::vector< std::string >* string_list );
better than this:
std::vector< std::string > Foo();
Does it matter what's in the container? For instance would returning a container like this:
struct buzz {
int a;
char b;
float c;
}
std::map< int, buzz > Foo();
be a more costly operation than this:
std::map< int, int > Foo();
Thanks,
PaulH
Edit:
This is with C++03. A C++0x solution is, unfortunately, not acceptable.
Edit2:
I am using the Microsoft Visual Studio 2008 compiler.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
C++03 可能会进行(命名)返回值优化(google RVO 和 NRVO)。
如果该优化不适用,C++0x 将移动语义。
C++03 will probably do (named) return value optimization (google RVO and NRVO).
If that optimization is not applicable, C++0x will do move semantics.
我不是100%确定,但是NO(感谢评论员):
输出(使用LOCAL_FUN):
编辑:更多地玩代码让我对局部变量(LOCAL_FUN)产生了一些乐趣。因此,一个不优化复制的非常糟糕的编译器实际上可能会破坏这段代码......
I wasn't 100% sure, but NO (thanks to the commentators) :
output (with LOCAL_FUN):
Edit: Some more playing with the code led me to some fun with the local variables (LOCAL_FUN). So a really bad compiler that does not optimize copying, can actually break this code...
是的,它将涉及容器的副本,但不要使用
void Foo( std::vector< std::string >* string_list );
。请改用void foo( vector& string_list);
。或者只是切换到 C++0x 并使用已经在库中实现移动优化的编译器。
Yes it will involve a copy of the container, but don't use
void Foo( std::vector< std::string >* string_list );
. Usevoid foo( vector<string>& string_list);
instead.Or just switch to C++0x and use a compiler that has already move optimizations implemented in the library.
首先要求编译器消除复制构造,如果不能,则移动,如果不能则复制。因此,如果您的编译器非常糟糕,您可能会面临额外副本的开销。有关详细信息,请参阅此讨论。
First compiler is required to elide copy construction, if can't, then move, if can't then copy. So if you have a really bad compiler, you risk incurring an overhead of an extra copy. See this discussion for details.
这取决于容器的复制构造函数。 C++ 具有按值传递语义。因此,当您为函数 Foo() 返回向量时,它将使用值语义返回,即将调用复制构造函数来复制向量的值。在这种情况下,std::vector 的复制构造函数创建一个新容器并复制值。如果将指针传递给容器,如果尚未分配内存,则必须分配内存,以便指针指向实际容器而不是空值。从编程实践的角度来看,这不是一件好事,因为你让语义有待解释。更好的想法是传递对容器的引用,并让函数用所需的元素填充容器。
It depends on the copy constructor of the container. C++ has pass by value semantics. So when you return a vector for function Foo() it will be returned using value semantics i.e. a copy constructor will be invoked to copy the value of the vector. In this case the copy constructor of std::vector creates a new container and copies the values. In case of passing a pointer to the container you would have to allocate the memory if you have not allocated it already so the pointer points to an actual container and not a null value. From a programming practice perspective this is not a good thing to do because you leave the semantics open to interpretation. Better idea would be to pass a reference to the container and let the function fill the container with the desired elements.