让我先声明我不知道我的目标是否可能,如果可能,我不知道如何找到信息。
OpenGL着色语言允许一种称为swizzeling的语法。
如果有一个向量
v {x, y, z}
可以通过以下方式构建新的向量
v.xxx, v.xxy, v.xxz, v.xyx, ... etc
总共有3 * 3 * 3 = 27个可能的选项。
我想在我自己的矢量库中实现这种特性。
以下是此类函数的一个示例:
vec3<T> xxx() const
{
vec3<T> v(x, x, x);
return v;
}
然后我可以编写另外26个函数来说明所有可能的选项,但这似乎是我应该能够使用宏来完成的事情。
vec3<T> (#A)(#B)(#C)() const
{
vec3<T> v(#A, #B, #C);
return v;
}
其中,#A、#B和#C是3个单个字符,编译器可使用x
、y
和z
选项对其进行扩展。
这样的事情在gcc/g++中可能吗?
3条答案
按热度按时间de90aj5v1#
有关
##
运算符的更多信息,请搜索“标记粘贴”。8e2ybdfx2#
您可以定义
以致
扩展到
现在你只需要像这样列出所有27种组合:
busg9geu3#
这绝对是可能的,尽管如果你想避免输入所有的组合,你需要一点宏样板。
你可以使用递归宏自动生成所有的a,b和c的组合,这样你就不必单独输入它们了--这对于vec 3来说可能没有必要(因为只有27种可能的混合),但是对于vec 4来说,它肯定会为你节省大量的输入,因为vec 4有256种可能的混合。(甚至更高维的vecs)
用法如下所示:
godbolt
其范围将扩大到:
对于这个实现,我使用了C++20中引入的新的
__VA_OPT__
标记。虽然对于递归宏来说,它不是严格必需的,但它使实现它们变得容易得多。下面是
FOR_EACH_COMBINATION
的完整代码(用于深入解释see here):godbolt
此外,
FOR_EACH_COMBINATION
宏还可以用于所有其他类型的恶作剧,如auto-generating explicit specializations of templates或generating an array of all possible 8-bit patterns:如果您想了解更多有关递归宏的信息,请阅读以下几本好书:
__VA_OPT__
其他参考资料:
FOR_EACH_COMBINATION
的问题)