我正在测量我在调试模式中运行的小演示的性能。这些操作似乎需要很长时间,并且正在进行复制操作(或者在调试时出现):
// Get access to the vertices and faces
auto vertices = t.GetVertices();
auto faces = t.GetFaces();
该功能的实现是:
std::vector<glm::vec3> const& GetVertices() const { return vertices_; }
std::vector<glm::ivec3> const& GetFaces() const { return faces_; }
在包含以下私有成员的类中:
private:
std::vector<glm::vec3> vertices_;
std::vector<glm::ivec3> faces_;
无论出于何种原因,我都希望返回一个const引用几乎不会导致性能损失,但是这个操作似乎真的让程序陷入困境。我在这里错过了什么?这是否在发布模式下得到优化,但总是在调试模式下发生?
答案 0 :(得分:8)
vertices
和faces
的类型分别为std::vector<glm::vec3>
和std::vector<glm::ivec3>
。初始化它们时,编译器需要从返回的引用中复制内容。
如果数据成员vertices
发生变化,编译器会假定您不希望vertices_
的内容发生变化;因为那是你宣布变量的方式。
如果您想将其声明为引用,则必须明确说明:
auto const& vertices = t.GetVertices ();
auto const& faces = t.GetFaces ();
faces
和vertices
的类型?使用表达式auto foo = init
,foo
将具有针对以下模板函数的参数推导出的类型,称为deduce_type (init)
作为其参数。
template<class T> void deduce_type (T);
// auto vertices = t.getVertices ();
deduce_type (t.getVertices ()) // imaginary call, T = std::vector<glm::vec3>
不,不是现在,但是在即将推出的 C ++标准( C ++ 14 )中,您将能够执行以下操作,结果将是您的不正确地期望您的原始代码:
decltype(auto) vertices = t.GetVertices ();
// ^-- vertices is of type `std::vector<glm::vec3> const&`
答案 1 :(得分:0)
您必须记住,使用/向另一个对象分配或初始化对象,将以某种方式结束该对象的副本。虽然您提供的函数会返回常量引用,但它们会被分配(或复制)到新的实例化中。
你可以通过使用指针(它将在指针的堆栈上分配内存,但IMO它是一个名义因子)来避免这种情况,或者你可以使用移动构造函数。在这种情况下,我不知道移动构造函数是否会起作用,但我最初的想法是它不会(因为指定的值应该是const)。