在 Visual C++ 2013 中分配给 const 引用

Assignment to const reference in Visual C++ 2013

在 Visual C++ 2013 中,为 const 引用分配一个临时值是合法的,例如

const int& a = 1;

在一个大型软件项目中,我现在偶然发现一行代码需要大约 10 毫秒才能执行:

const std::vector<Item>& desc = (hasItems) ? instance->getItems() : std::vector<Item>();

Item 是一个大约有 20 个字节的结构,instance->getItems() returns a const std::vector<项目>&。 我没有看到为什么这条线需要比瞬间更长的时间来执行,所以我玩了一下发现

const std::vector<Item>& desc = std::vector<Item>();

也需要 10 毫秒,而

std::vector<Item> items;
const std::vector<Item>& desc = items;

接近即时,即 0.00.. ms,如您所料。

事实是,我可以在现有的复杂软件项目中可靠地重现此问题,但在任何精简的最小示例中,两个版本 运行 同样快。我已经在启用优化的发布版本中测试了所有这些。这些优化之一是否有可能使这个异常为 const 引用赋值真的很慢?我真的很想知道是什么导致了这种行为。有谁知道是什么原因造成的?

跟进,是否有警告为我不小心禁用的常量引用赋值?如果是这样,它的 ID 是什么?如果编译器可以指出代码中发生这种情况的其他地方,那将会很方便。

编辑:计时是在感兴趣的代码前后用一个简单的 CPU 时钟完成的,除以每秒的时钟周期数。它不太准确,但可以让您大致了解 10.something 和 0.something 之间的区别。而且它没有以任何方式波动,在这个特定示例中它是完全可重现的。执行时间有显着差异。

const std::vector<Item>& desc =
      (hasItems) ? instance->getItems() : std::vector<Item>();

您可能出乎意料,但此行复制了 getItems 的 return 值所引用的向量。

形式上,条件运算符执行的类型强制转换规则密谋使它成为现实。实际上,编译器别无选择:当引用绑定到临时对象时,编译器需要生成代码以在引用最终超出范围时销毁该临时对象 - 但如果可以绑定相同的引用,那将变得棘手有时是临时的,有时是左值。正是为了避免这种情况,编写类型强制规则以确保在您的情况下在条件的两个分支上创建一个临时文件。

这样的事情应该有所帮助:

std::vector<Item> blank;
const std::vector<Item>& desc =
      (hasItems) ? instance->getItems() : blank;

或者,我想,您可以将 getItems() 设计为 return 对没有项目的有效空向量的引用,并且不需要调用者跳转。为此目的保留一个静态的始终为空的向量变量并非不合理。