在C++中乘以用户定义的数组

Multiplying user-defined arrays in C++

本文关键字:定义 数组 用户 C++      更新时间:2023-10-16

我有以下代码:

#include <iostream>
#include <array>
typedef std::array<int, 2> eval_t;
eval_t operator*(eval_t e1, eval_t e2) { return {e1[0] * e2[0], e1[1] * e2[1]}; }
int main()
{
    eval_t a = {1, 2};
    eval_t b = a * {2, 1};
    std::cout << "b = (" << b[0] << ',' << b[1] << ')' << std::endl;
}

GCC 拒绝编译我的乘法:

$ g++ -std=c++11 test.cc 
test.cc: In function ‘int main()’:
test.cc:10:17: error: expected primary-expression before ‘{’ token
  eval_t b = a * {2, 1};
                 ^

我天真地希望唯一可能的运算符*()将eval_t作为左操作数,将是我定义的运算符,并且右操作数将被理解为eval_t

相反,如果我写:

eval_t a = {1, 2};
eval_t v = {2, 1};
eval_t b = a * v;

它有效。

std::array是一个

聚合,它没有像其他容器那样接受std::initializer_list作为参数的构造函数,因此程序无法从initializer_list创建eval_t。因此,编译器找不到运算符重载函数的匹配类型,因此失败。

因此,{1, 2}无法按预期隐式转换为eval_t

根据标准,二进制运算符不允许使用纯大括号初始值设定项,因此编译器将拒绝它。但在返回声明中是允许的。 此答案中解释了更多详细信息:运算符的初始值设定项列表和 RHS

如果按如下方式更改语句,它将起作用

eval_t b = a * eval_t{{2, 1}};

只是一个语法错误。将行更正为这些。

return{ { e1[0] * e2[0], e1[1] * e2[1] } };

eval_t b = a * eval_t{ { 2, 1 } };

测试:

#include <iostream>
#include <array>
typedef std::array<int, 2> eval_t;
eval_t operator*(eval_t e1, eval_t e2) 
{
    return{ { e1[0] * e2[0], e1[1] * e2[1] } };
}
int main()
{
    eval_t a = { 1, 2 };
    eval_t b = a * eval_t{ { 2, 1 } };
    std::cout << "b = (" << b[0] << ',' << b[1] << ')' << std::endl;
    // b = (2,2)   
}

你也可以考虑不要定义你自己的重载operator*,以利用标准库:

std::array<int, 2> a = {1, 2};
std::array<int, 2> b = {2, 1};
std::array<int, 2> c;
std::transform(a.begin(), a.end(), b.begin(), c.begin(), std::multiplies<int>());

现场演示