解压枚举的可变参数包

Ale*_*ter 6 c++ enums templates variadic

更新:编辑以修复工作示例中的编译。

我想做类似下面的事情,以便该函数可以接受枚举类实例的列表或保存它们的结构,但是 的定义auto myFunc2<EList<Types...>>失败expected a constant not E::A

#include <cstdint>
#include <iostream>

enum class E {A = 0, B=1};
template<E... Types> struct tl2 {};
using my_list_2 = tl2<E::A>;

template <E ... Types>
auto myFunc2 = [] {
    std::cout << "Size: " << sizeof...(Types) << std::endl;     
};

template <template<E...> typename EList, E... Types>
auto myFunc2<EList<Types...>> = [] {
    std::cout << "Size: " << sizeof...(Types) << std::endl;     
};

int main() {
    myFunc2<E::A, E::B>();  // This call prints size of typelist
                            //Works when myFunc2<Elist<Types..>> is commented out

    //myFunc2<my_list_2>();      //This breaks      
} 
Run Code Online (Sandbox Code Playgroud)

如果我们将其转换为通用类型,那么一切都会按预期编译和工作。例如:

#include <cstdint>
#include <iostream>

template < typename ... Types > struct tl
{
};
using my_list = tl <int, float, uint64_t>;

template <typename ... Types>
static constexpr auto myFunc2 = [] {
    std::cout << "Size: " << sizeof...(Types) << std::endl;   
};

template <template<class...> class TL, typename ... Types>
static constexpr auto myFunc2<TL<Types...>> = [] {
    std::cout << "Size: " << sizeof...(Types) << std::endl;   
};

int main() {
    myFunc2<int,uint64_t,bool,uint16_t>();
    myFunc2<my_list>();                    
} 
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?枚举类作为模板处理的方式是否有限制?

Dav*_*ing 2

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

\n
template <E ... Types>\nvoid myFunc2() {\n    std::cout << "Size: " << sizeof...(Types) << std::endl;     \n}\n\nnamespace detail {\ntemplate <template<E...> typename EList, E... Types>\nvoid myFunc2(EList<Types...>>) {\n    std::cout << "Size: " << sizeof...(Types) << std::endl;     \n}\n}\n\ntemplate <typename EList>\nvoid myFunc2() {\n    detail::myFunc2(EList());\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这种方法允许 \xe2\x80\x9cone template\xe2\x80\x9d 接受不同类型的模板参数,因为具有错误类型模板参数的模板将在重载解析期间被忽略。

\n