如何使c++函数隐式地将整型数列表转换为矢量形参

How do I make a C++ function implicitly convert a list of ints into a vector parameter?

本文关键字:转换 列表 数列 形参 整型 c++ 何使 函数      更新时间:2023-10-16

我正在研究一个库,其函数通常采用向量类型(__v4si,或4个有符号整数的向量)作为参数。(注意到目前为止,这与 c++ STL vector模板类无关;这是一个更基本的构造,用于让编译器生成向量化 SIMD代码。)

在我的C代码中,我通常调用包装器宏,该宏接受int参数列表并初始化__v4si,如下所示:

#define MakeIndex(dims...) ((__v4si){ dims })

这当然在 c++ 中也工作得很好,但是我想利用 c++ 更具表现力的类型系统来清理对我的库api的调用。例如,我现在这样写:

long idx = IndexDotProduct(MakeIndex(1, 2, 3), MakeIndex(4, 5, 6, 7));

宏展开为:

long idx = IndexDotProduct(((__v4si){1, 2, 3}), ((__v4si){4, 5, 6, 7}));

我希望能够这样写:

long idx = IndexDotProduct({1, 2, 3}, {4, 5, 6, 7});

所以,本质上(我认为)我想定义一个类,它只是围绕原始__v4si类型的语法糖,但它有一个隐式的列表初始化操作符。

如何在 c++ 11中做到这一点?

<标题> 解决方案

下面是一个适用于C c++ 代码的公式(现在使用从我的库头文件中复制和粘贴的更详细的名称):

typedef struct vMAT_Index {
    __v4si v;
#ifdef __cplusplus
    vMAT_Index(__v4si v) : v(v) { }
    vMAT_Index(int v0 = 0, int v1 = 0, int v2 = 0, int v3 = 0) : v((__v4si){ v0, v1, v2, v3 }) { }
#endif
} vMAT_Index;
#define vMAT_MakeIndex(dims...) ((vMAT_Index){ .v = { dims } })
static inline long
vMAT_Index_dot(vMAT_Index a,
               vMAT_Index b)
{
    __v4si c = a.v * b.v;
    return (long)c[0] + c[1] + c[2] + c[3];
}

C代码中,您仍然像这样使用helper宏:

long idx = vMAT_Index_dot(vMAT_MakeIndex(1, 2, 3), vMAT_MakeIndex(4, 5, 6, 7));

但是现在在 c++ 中你可以直接写:

long idx = vMAT_Index_dot({ 1, 2, 3 }, { 4, 5, 6, 7 });

感谢nosid提供必要的答案!

使用隐式构造函数从大括号初始化列表自动创建vector对象:

struct vector
{
    vector(__v4si v);
    vector(int i0, int i1, int i2, int i3);
};
long IndexDotProduct(vector lhs, vector rhs);
long idx = IndexDotProduct(((__v4si){ 1, 2, 3 }), { 4, 5, 6, 7 });