我正在开发一个库,其函数通常采用矢量类型(__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 代码中,您仍然使用辅助宏,如下所示:
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提供必要的答案!
答案 0 :(得分:1)
使用隐式构造函数从大括号初始化列表中自动创建向量对象:
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 });