C++ Segfaults当声明/定义一个返回自动返回类型的valarray的函数时

C++ Segfaults当声明/定义一个返回自动返回类型的valarray的函数时,c++,auto,c++14,C++,Auto,C++14,有人能帮我理解为什么下面的代码会出错吗?如果我声明/定义mk以返回std::valarray,代码就会工作。我想我不太清楚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] &l

有人能帮我理解为什么下面的代码会出错吗?如果我声明/定义
mk
以返回
std::valarray
,代码就会工作。我想我不太清楚
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;
}
#包括
#包括
自动mk(int x)
{
返回x*std::valarray{1};
}
int main()
{
自动v=mk(3);

std::cout
std::valarray
使用表达式模板。表达式模板不能很好地使用返回类型推断

在本例中,
x*std::valarray{1}
返回一个表达式,表示“将
x
乘以一些
std::valarray
。当您在
mk
之外使用对象时,
x
std::valarray
都已超出范围

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

它不会复制它的参数,因为表达式模板可以有效地避免这样做。代价是它们不能很好地使用
auto


有一些建议添加与
运算符auto
等效的内容,即当您希望持久存储或返回某个类型的实例时,应推断出的类型,以使表达式模板更透明。如果建议继续,则表达式模板会说“将我存储为
valarray
"不知怎的。我不知道这些建议的当前状态。

该代码在函数
mk
中没有
x*
部分的情况下也可以运行。这段代码在gcc c c++11中编译并运行良好。不过它确实警告了我返回类型。它确实使用c++14的g++v4.9.2进行编译,但不使用c++11。如果没有优化,它会打印出
32767
。使用
-O2
它会打印出
3
。使用clang++v3.5.1编译,它总是分段错误。
typeid(v).name()的输出
在这里很有见地。我刚刚用gcc-4.9.2试用过。对于
auto
版本,它是
St5\u ExprISt8\u BinClosISt12\u乘数st9\u ConstantSt9\u valarrayiie1970481344
。对于显式返回类型的版本,
St8valarrayIiE3