Я работаю над библиотекой, функции которой обычно принимают векторный тип (__v4si
или вектор из 4-х знаков со знаком) в качестве параметра. (Обратите внимание, что пока это не имеет ничего общего с C ++ STL vector
шаблон класса; это более примитивная конструкция, используемая для генерации компилятором Векторизованных SIMD код.)
В моем С код, который я обычно называю макросом-оберткой, который принимает список аргументов 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 ++ код (теперь используется больше подробных имен, скопированных и вставленных из заголовочных файлов моей библиотеки):
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];
}
В С код вы все еще используете вспомогательный макрос, как это:
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 за предоставленный ответ!
Используйте неявные конструкторы для автоматического создания векторного объекта из списка инициализаторов фигурных скобок:
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 });
Других решений пока нет …