英文:
Unpacking Variadic Parameter Pack of Enums
问题
以下是您要求的翻译:
更新:已编辑以修复工作示例中的编译问题。
我想要做类似以下的事情,以便该函数可以接受枚举类实例的列表或保存它们的结构体,但是“auto myFunc2<EList<Types...>>”的定义失败,出现“期望常数而不是E::A”的错误。
```cpp
#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>(); // 此调用打印类型列表的大小
// 当注释掉myFunc2<Elist<Types..>>时可以正常工作
// myFunc2<my_list_2>(); // 这会导致错误
}
如果将此转换为通用类型,则一切都会编译并按预期工作。例如:
#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>();
}
这里发生了什么?枚举类在模板中的处理是否存在限制?
希望这可以帮助您理解问题所在。如果您需要更多信息或有其他问题,请随时提问。
英文:
Update: Edited to fix compilation in working example.
I want to do something like the following so the function can take in both a list of the enum class instances or a struct that holds them, but the definition of auto myFunc2<EList<Types...>>
fails with 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
}
If we convert this to general types then everything compiles and works as expected. For example:
#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>();
}
What is going on here? Is there a limitation in how enum classes can be handled as templates?
答案1
得分: 2
真正的函数模板可以做到这一点(通常需要额外的辅助来推导参数包):
```cpp
template <typename... Types>
void myFunc2() {
std::cout << "Size: " << sizeof...(Types) << std::endl;
}
namespace detail {
template <template<typename...> typename EList, typename... Types>
void myFunc2(EList<Types...>) {
std::cout << "Size: " << sizeof...(Types) << std::endl;
}
}
template <typename EList>
void myFunc2() {
detail::myFunc2(EList());
}
这种方法使得“一个模板”能够接受不同种类的模板参数,因为具有错误种类的模板参数的模板将在重载解析过程中被忽略。
<details>
<summary>英文:</summary>
True **function** templates can do this (with the usual extra helper for deducing a pack):
template <E ... Types>
void myFunc2() {
std::cout << "Size: " << sizeof...(Types) << std::endl;
}
namespace detail {
template <template<E...> typename EList, E... Types>
void myFunc2(EList<Types...>>) {
std::cout << "Size: " << sizeof...(Types) << std::endl;
}
}
template <typename EList>
void myFunc2() {
detail::myFunc2(EList());
}
This approach allows “one template” to accept template arguments of different **kinds** because the templates with the wrong kinds of template parameters will simply be ignored during overload resolution.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论