首页 >后端开发 >C++ >如何使用包扩展在 C 中迭代参数包?

如何使用包扩展在 C 中迭代参数包?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-12-24 10:59:13506浏览

How Can I Iterate Over a Parameter Pack in C   Using Pack Expansion?

可变参数模板:解开迭代的包扩展

可变参数模板在 C 中赋予了卓越的表现力,但冒险进入它们的领域可能会揭示不可预见的复杂性。当尝试使用包扩展迭代参数包时,就会出现这样的挑战。考虑以下代码:

template<typename T>
static void bar(T t) {}

template<typename... Args>
static void foo2(Args... args)
{
    (bar(args)...);
}

int main()
{
    foo2(1, 2, 3, "3");
    return 0;    
}

编译时,此代码遇到错误:“'args':参数包必须在此上下文中扩展。”该问题源于无法在函数调用中直接扩展参数包。

解决方案在于在花括号初始化列表中利用包扩展,这是一个明确允许此类扩展的上下文。通过将扩展放置在虚拟数组的初始值设定项列表中,我们可以强制执行所需的行为:

template<typename... Args>
static void foo2(Args &amp;&amp;... args)
{
    int dummy[] = { 0, ( (void) bar(std::forward<Args>(args)), 0) ... };
}

此修订后的代码采用细致的方法来确保正确的评估:

  • 防止空扩展: 空 Args 将导致长度为 0 的数组,这在 C 中是非法的。为了防止这种情况,我们确保数组至少包含一个元素。
  • 完美转发:我们使用完美转发(std::forward)来避免潜在的副本并保留潜在的 const 限定符。
  • 中和返回类型:我们将 bar() 的返回值转换为 void 以利用内置逗号运算符,确保从左到右求值。

在 C 17 中,折叠表达式提供了更紧凑的解决方案:

((void) bar(std::forward<Args>(args)), ...);
```

This approach guarantees the desired left-to-right expansion unequivocally.

以上是如何使用包扩展在 C 中迭代参数包?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn