c++ 枚举的变参数包解包

izj3ouym  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(229)

更新:编辑以修复工作示例中的编译。
我想做类似于下面的操作,这样函数就可以接受枚举类示例的列表或包含它们的结构体,但是auto myFunc2<EList<Types...>>的定义失败了,expected a constant not E::A

  1. #include <cstdint>
  2. #include <iostream>
  3. enum class E {A = 0, B=1};
  4. template<E... Types> struct tl2 {};
  5. using my_list_2 = tl2<E::A>;
  6. template <E ... Types>
  7. auto myFunc2 = [] {
  8. std::cout << "Size: " << sizeof...(Types) << std::endl;
  9. };
  10. template <template<E...> typename EList, E... Types>
  11. auto myFunc2<EList<Types...>> = [] {
  12. std::cout << "Size: " << sizeof...(Types) << std::endl;
  13. };
  14. int main() {
  15. myFunc2<E::A, E::B>(); // This call prints size of typelist
  16. //Works when myFunc2<Elist<Types..>> is commented out
  17. //myFunc2<my_list_2>(); //This breaks
  18. }

如果我们将其转换为一般类型,那么一切都可以编译并按预期工作。例如:

  1. #include <cstdint>
  2. #include <iostream>
  3. template < typename ... Types > struct tl
  4. {
  5. };
  6. using my_list = tl <int, float, uint64_t>;
  7. template <typename ... Types>
  8. static constexpr auto myFunc2 = [] {
  9. std::cout << "Size: " << sizeof...(Types) << std::endl;
  10. };
  11. template <template<class...> class TL, typename ... Types>
  12. static constexpr auto myFunc2<TL<Types...>> = [] {
  13. std::cout << "Size: " << sizeof...(Types) << std::endl;
  14. };
  15. int main() {
  16. myFunc2<int,uint64_t,bool,uint16_t>();
  17. myFunc2<my_list>();
  18. }

这是怎么回事?在如何将枚举类作为模板处理方面有限制吗?

b5buobof

b5buobof1#

真正的函数模板可以做到这一点(使用通常用于推导包的额外助手):

  1. template <E ... Types>
  2. void myFunc2() {
  3. std::cout << "Size: " << sizeof...(Types) << std::endl;
  4. }
  5. namespace detail {
  6. template <template<E...> typename EList, E... Types>
  7. void myFunc2(EList<Types...>>) {
  8. std::cout << "Size: " << sizeof...(Types) << std::endl;
  9. }
  10. }
  11. template <typename EList>
  12. void myFunc2() {
  13. detail::myFunc2(EList());
  14. }

这种方法允许“一个模板”接受不同类型的模板参数,因为在重载解析期间,具有错误类型的模板参数的模板将被简单地忽略。

展开查看全部

相关问题