习惯用x宏来生成强大的代码。我特别喜欢的功能之一是我不能弄乱值的顺序,也不能忘记一个。
我想知道数组和函数参数是否有类似的策略
例如:
如果一个库提供了一个函数:
void foobar(std::string_view k, std::string_view l, std::string_view m);
在我的代码库中我有:
constexpr std::array<std::string_view, 3> kConstants{"one", "two", "three"};
我可以做一些扩展魔法来得到类似的东西:
foobar(kConstants);
注意这对我有用我必须在不修改
foobar
的情况下执行此操作。我知道我可以用 x 宏做这样的事情。
我可以做一些扩展魔法来得到类似的东西:
?请注意这对我有用我必须在不修改foobar(kConstants)
的情况下执行此操作。我知道我可以用 x macros 做这样的事情。foobar
是的,这可以通过模板元编程实现,如下所示。另请注意,如果可以选择使用模板,则无需使用 macros。
在下面的程序中,我创建了一个函数模板,用于收集数组元素,然后将递归结束时的 传递给
foobar
。请注意,我将该函数命名为 helperOfFoobar
,但您也可以将其命名为 foobar
,这也将起作用,因为 C++ 支持函数和函数模板的重载。 演示
//to end recursion
template<std::size_t N, typename... Elements> void helperOfFoobar(const std::array<std::string_view, N>& arr, Elements... elements)
requires (sizeof...(elements) == N)
{
foobar(elements...); //since this is the end of recursion, we call foobar by passing all the collected elements
//just for debugging I am print the elements
((std::cout << elements << ' '), ...); //PRINTS: one two three AS EXPECTED
}
//recursively call this and pass elements as arguments
template<std::size_t N, typename... Elements> void helperOfFoobar(const std::array<std::string_view, N>& arr, Elements... elements)
requires (sizeof...(elements) != N)
{
helperOfFoobar(arr, elements..., arr[sizeof...(elements)]); //collect array elements and pass them recusively
}
constexpr std::array<std::string_view, 3> kConstants{"one", "two", "three"};
int main()
{
helperOfFoobar(kConstants);
}
另请注意,
foobar
/中没有任何修改,因为这是您的要求。
最后,通过将
requires
子句更改为 enable_if
,这可以很容易地(平凡地)转换为与 C++17 一起工作。