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

时间:2015-03-04 20:14:11

标签: c++ auto c++14

有人可以帮我理解为什么以下代码段错误?如果我声明/定义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;
}

1 个答案:

答案 0 :(得分:6)

std::valarray使用表达式模板。表达式模板在返回类型扣除方面效果不佳。

在这种情况下,x*std::valarray<int>{1}会返回一个表达式,表示“x乘以std::valarray<int>。当您使用mk之外的对象时,x std::valarray<int> 1}}和auto已超出范围。

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

它不会复制其参数,因为表达式模板通过避免这样做是有效的。费用是他们与operator auto打得不好。

有一些建议要添加等同于valarray的内容 - 当您想要持久存储或返回类型的实例时应该推断出的类型 - 以使表达式模板更透明。如果这样的提案在哪里继续,那么表达式模板会以某种方式说“以{{1}}存储我”。我不知道这些提案的现状。