我需要定义一个接受多个 3D 坐标作为参数的 C++ 模板。当这些坐标的所有维度都定义为单独的整数变量时,参数列表将变得非常长 - 3 个坐标需要 9 个参数,这使得模板难以使用。
因此,非常希望以使用编译时数组的方式声明模板。它们的默认参数也应该直接在模板声明的位置声明为值,而不是变量名。
经过一些实验,令我惊讶的是,我发现 GCC 13 将接受以下 C++ 程序std=c++20
:
#include <cstdio>
#include <array>
template <
std::array<int, 3> offset = {0, 0, 0}
>
struct Array
{
void operator() (int i, int j, int k)
{
printf("(%d, %d, %d)\n", i + offset[0], j + offset[1], k + offset[2]);
}
};
int main(void)
{
Array arr_default;
arr_default(0, 0, 0);
Array<{1, 1, 1}> arr;
arr(0, 0, 0);
return 0;
}
然而,clang 18 拒绝使用braced-init-list,因为它无效:
test2.cpp:5:30: error: expected expression
5 | std::array<int, 3> offset = {0, 0, 0}
| ^
test2.cpp:17:8: error: no viable constructor or deduction guide for deduction of template arguments of 'Array'
17 | Array arr_default;
| ^
test2.cpp:7:8: note: candidate template ignored: couldn't infer template argument 'offset'
7 | struct Array
| ^
test2.cpp:7:8: note: candidate function template not viable: requires 1 argument, but 0 were provided
7 | struct Array
| ^~~~~
test2.cpp:20:8: error: expected expression
20 | Array<{1, 1, 1}> arr;
| ^
3 errors generated.
问题
它真的是合法的C++程序吗?如果是,我应该使用什么语法来说服 clang 接受它?如果不是,我是否应该报告 GCC 错误以毫无疑问地接受它?
是否有替代且更兼容的方式来实现我的目标?
std::array
不必使用,任何其他具有同等效果的方法也可以。