【发布时间】:2020-01-25 22:08:26
【问题描述】:
我尝试了以下程序
#include <iostream>
#include <valarray>
int main( void )
{
std::valarray<int> v1 = { 1, 2, 3, 4, 5 };
std::valarray<int> v2 = { 1, 2, 3, 4, 5 };
auto v3 = v1 * v2;
for ( const auto &item : v3 ) std::cout << item << ' ';
std::cout << '\n';
return 0;
}
并收到一条错误消息,指出此语句中隐式使用了 v3 的适当函数 begin
for ( const auto &item : v3 ) std::cout << item << ' ';
找不到。
所以我尝试了以下代码
#include <iostream>
#include <valarray>
#include <type_traits>
int main( void )
{
std::valarray<int> v1 = { 1, 2, 3, 4, 5 };
std::valarray<int> v2 = { 1, 2, 3, 4, 5 };
auto v3 = v1 * v2;
std::cout << std::is_same<std::valarray<int>, decltype( v3 )>::value << '\n';
return 0;
}
得到结果
0
但是当这种说法
auto v3 = v1 * v2;
改为
std::valarray<int> v3 = v1 * v2;
那么输出就是
1
std::valarray<int> 的 operator * 声明如下
template<class T> valarray<T> operator* (const valarray<T>&, const valarray<T>&);
那么是std::valarray<int>的实现的bug吗?
【问题讨论】:
-
如果将
auto v3 = ...替换为std::valarray<int> v3 = ...,代码将按预期编译和运行。通过使用auto,v3是一些中间表达式模板生成的类型。 -
valarray上的操作员被允许返回代理对象,这使得实现可以将多个操作(如a * b + c)优化到一个循环中。不知道代理对象是否需要实现begin()和end()。 -
见eel.is/c++draft/valarray.syn#3.sentence-1,这意味着你不能使用
auto,并且对它有你正在测试的期望。
标签: c++ gcc operator-overloading c++20 valarray