有人可以帮我理解为什么以下代码段错误?如果我声明/定义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;
}
答案 0 :(得分:6)
std::valarray
使用表达式模板。表达式模板在返回类型扣除方面效果不佳。
在这种情况下,x*std::valarray<int>{1}
会返回一个表达式,表示“x
乘以std::valarray<int>
。当您使用mk
之外的对象时,x
std::valarray<int>
1}}和auto
已超出范围。
然后尝试使用这些对象(在它们过期后):在测试中,会产生段错误。经典的未定义行为。
它不会复制其参数,因为表达式模板通过避免这样做是有效的。费用是他们与operator auto
打得不好。
有一些建议要添加等同于valarray
的内容 - 当您想要持久存储或返回类型的实例时应该推断出的类型 - 以使表达式模板更透明。如果这样的提案在哪里继续,那么表达式模板会以某种方式说“以{{1}}存储我”。我不知道这些提案的现状。