当我使用valarray
编写简单的算术表达式并将结果分配给auto
时,我在尝试访问gcc上的结果时会得到一个段错误。
#include <iostream>
#include <valarray>
using std::ostream; using std::valarray;
ostream& operator<<(ostream&os, const valarray<double>&vs) {
os << "[";
for(auto&v : vs) os << v << " ";
return os << "]";
}
int main() {
valarray<double> a{ 1.0, 2.0, 3.0, 4.0 };
std::cout << "a: " << a << "\n";
valarray<double> b{ 2.0, 4.0, 6.0, 8.0 };
std::cout << "b: " << b << "\n";
valarray<double> c{ 2.0, 1.5, 0.5, 0.25 };
std::cout << "c: " << c << "\n";
valarray<double> x = ( a + b ) / 2;
std::cout << "x: " << x << "\n";
// this still works:
auto y = ( a + b ) / 2;
// The following will result in a segfault:
std::cout << "y:" << y << "\n";
}
参考资料中指出,实现可能选择重载算术操作时返回的类型不是valarray
值,而是“类似于它”的东西:
返回
valarray
的运算符可以返回一个不同类型的对象。该类型需要能够隐式转换为valarray
,并且支持作为所有带有valarray&
参数的函数的参数。这允许写入复制实现。
我的operator<<
应该调用那个“隐式转换”,不是吗?
那我为什么会收到段错误?
$ ./valarray01.cpp.x
a: [1 2 3 4 ]
b: [2 4 6 8 ]
c: [2 1.5 0.5 0.25 ]
x: [1.5 3 4.5 6 ]
Segmentation fault (core dumped)
gcc版本为6.2.0 20160901 (Ubuntu 6.2.0-3ubuntu11~14.04)
我尝试了一下clang(在Linux上,所以可能是gcc的stdlib),有些怀疑,但结果显示它可以运行:
clang版本为3.9.1-svn288847-1~exp1 (分支/release_39)
$ ./valarray01.cpp.x
a: [1 2 3 4 ]
b: [2 4 6 8 ]
c: [2 1.5 0.5 0.25 ]
x: [1.5 3 4.5 6 ]
y:[1.5 3 4.5 6 ]
嗯,在我提交gcc-bug之前... 我是做错了什么吗?我的 auto
是有问题的吗?还是真的是gcc的问题?
std::_Expr<std::_BinClos<std::__divides,std::_Expr,std::_Constant,std::_BinClos<std::__plus,std::_ValArray,...
等等。好吧,也许只是脆弱/难以处理的代码,在后来的gcc版本中已经修复了。 - towiauto
。 - Marc Glisse