繁体   English   中英

g++ 和 clang++ 都被模板函数参数包扩展所困扰?

[英]g++ and clang++ are both bugged with template function parameter pack expansion?

这是另一个问题的后续,其中一个答案将我的注意力引向了 Templates [temp.param] 17.1.17(最新的 C++17 草案,但我想也是之前的标准化),其中指出

作为包扩展的模板参数包不应扩展在同一模板参数列表中声明的参数包。

以这种限制为例

template <class... T, T... Values> // error: Values expands template type parameter struct static_array; // pack T within the same template parameter list

因此,如果我正确理解此规则,则以下功能(我认为非常合理)是非法的

template <typename ... Types, Types ... Values>
void foo (std::integral_constant<Types, Values>...)
 { ((std::cout << Values << std::endl), ...); }

因为第二个参数包 ( Types ... Values ) 扩展了在同一模板参数列表中声明的参数包 ( Types )。

无论如何,g++(9.2.0,示例)和clang++(8.0.0,示例)都可以毫无问题地编译以下代码

#include <iostream>
#include <type_traits>

template <typename ... Types, Types ... Values>
void foo (std::integral_constant<Types, Values>...)
 { ((std::cout << Values << std::endl), ...); }

int main()
 {
   foo(std::integral_constant<int, 0>{},
       std::integral_constant<long, 1L>{},
       std::integral_constant<long long, 2LL>{});
 }

所以我想我有什么误解。

g++ 和 clang++ 都被窃听了还是我误解了标准?

这是违法的,标准很明确。 就其价值而言,MSVC 似乎不接受代码( https://godbolt.org/z/DtLJg5 )。 这是一个 GCC 错误和一个Clang 错误 (我没有检查旧版本。)

作为一种解决方法,您可以执行以下操作:

template <typename... ICs>
std::enable_if_t<std::conjunction_v<is_integral_constant<ICs>...>> foo(ICs...)
{
    ((std::cout << ICs::value << '\n'), ...);
}

现场演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM