声明/定义函数返回具有自动返回类型的valarray时的Segfaults

jxy*_*jxy 4 c++ auto c++14

有人可以帮我理解为什么以下代码段错误?如果我声明/ define mk返回,代码可以工作std::valarray<int>.我想我不太清楚auto这里有什么.

#include <iostream>
#include <valarray>
auto mk(int x)
{
    return x * std::valarray<int>{1};
}
int main()
{
    auto v = mk(3);
    std::cout << v[0] << std::endl;
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

Yak*_*ont 6

std::valarray使用表达模板.表达式模板在返回类型推断方面效果不佳.

在这种情况下,x*std::valarray<int>{1}返回,说:"乘表达x一些std::valarray<int>.到时候你使用的对象外mk,都xstd::valarray<int>下降超出范围.

然后它尝试使用这些对象(在它们过期后):在测试中,会产生段错误.经典的未定义行为.

它不会复制其参数,因为表达式模板通过避免这样做是有效的.成本是他们玩得不好auto.

有一些建议要添加相当于的东西operator auto- 当你想要持久存储或返回一个类型的实例时应该推断出的类型 - 使表达式模板更透明.如果这样的提议在哪里继续,那么表达模板会说valarray"以某种方式将我存储为".我不知道这些提案的现状.

  • `typeid(v).name()`的输出在这里非常有见地.我刚用gcc-4.9.2尝试过.对于`auto`版本,它是`St5_ExprISt8_BinClosISt12__multipliesSt9_ConstantSt9_ValArrayiiEiE1970481344`.对于具有显式返回类型的那个,`St8valarrayIiE3`. (2认同)