我有以下代码:
#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;
它有效。
答案 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>());