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

时间:2015-06-20 22:45:27

标签: c++ c++11

我有以下代码:

#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;

它有效。

3 个答案:

答案 0 :(得分:3)

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

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

根据标准,二进制运算符不允许使用纯支撑初始化器,因此编译器将拒绝它。但它在返回声明中是允许的。此答案中解释了更多详细信息:Initializer lists and RHS of operators

如果您更改语句如下,它将起作用

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

答案 1 :(得分:2)

只是语法错误。 纠正这些行。

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)   

}

答案 2 :(得分:0)

您也可以考虑使用标准库,而不是定义自己的重载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>());

LIVE DEMO