将 constexpr 数组扩展为位置函数参数

问题描述 投票:0回答:2

习惯用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 宏做这样的事情。

c++ metaprogramming c++20 template-meta-programming
2个回答
7
投票

您正在寻找

std::apply

std::apply(foobar, kConstants);

0
投票

我可以做一些扩展魔法来得到类似的东西:

foobar(kConstants)
?请注意这对我有用我必须在不修改
foobar
的情况下执行此操作。我知道我可以用 x macros 做这样的事情。

是的,这可以通过模板元编程实现,如下所示。另请注意,如果可以选择使用模板,则无需使用 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 一起工作。

© www.soinside.com 2019 - 2024. All rights reserved.