英文:
Call template function with typename combinations
问题
我想循环遍历一个"类型名称列表",并查看它们的所有组合。我考虑使用元组来实现这一点,比较:
template<typename T, typename R>
void foo() {
std::cout << std::numeric_limits<T>::max() << ", " << std::numeric_limits<R>::max();
}
void call() {
using int_types = std::tuple<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t>;
// 只是为了可视化我的想法,这段代码不起作用!(请参见注释)
constexpr auto indices = std::make_integer_sequence<size_t, 8>();
for (auto i: indices) {
using T = std::tuple_element_t<i, int_types>;
for (auto j: indices) {
using R = std::tuple_element_t<j, int_types>;
foo<T, R>();
}
}
}
当然,for循环不是consteval,因此这种方法不起作用。我认为可以使用STL的递归或一些consteval功能来解决,但我还没有完全弄清楚。
英文:
I want to loop over a "list of typenames" and look at all combinations of them. I was thinking of using a tuple for this, compare:
template<typename T, typename R>
void foo() {
std::cout << std::numeric_limits<T>::max() << ", " << std::numeric_limits<R>::max();
}
void call() {
using int_types = std::tuple<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t>;
//Just to visualize my idea, this code does not work! (see comments)
constexpr auto indices = std::make_integer_sequence<size_t, 8>();
for (auto i: indices) {
using T = std::tuple_element_t<i, int_types>;
for (auto j: indices) {
using R = std::tuple_element_t<j, int_types>;
foo<T, R>();
}
}
}
Of course for loops are not consteval, thus this approach does not work. I think it might work using recursion or some consteval stuff from the STL but I can't quite figure it out.
答案1
得分: 2
您可以以这种方式扩展包
使用 int_types = std::tuple<int8_t, uint8_t, int16_t, uint16_t,
int32_t, uint32_t, int64_t, uint64_t>;
[]<typename... Ts>(std::tuple<Ts...>){
[]<typename T, typename... Us>(std::type_identity
(foo<T, Us>(), ...);
}(std::type_identity
}(int_types{});
[演示](https://godbolt.org/z/K7K9q3hPG)
英文:
You can expand pack that way
using int_types = std::tuple<int8_t, uint8_t, int16_t, uint16_t,
int32_t, uint32_t, int64_t, uint64_t>;
[]<typename... Ts>(std::tuple<Ts...>){
([]<typename T, typename... Us>(std::type_identity<T>, std::tuple<Us...>){
(foo<T, Us>(), ...);
}(std::type_identity<Ts>{}, int_types{}), ...);
}(int_types{});
答案2
得分: 2
这是一个基于索引的版本,其中内部 lambda 函数可以访问具体的索引,比如 L
和 K
。在这个版本中,如果需要的话,你可以进行验证,例如,如果索引相等,你可以选择排除对 foo
的调用:
void call() {
using int_types = std::tuple<int8_t, uint8_t, int16_t, uint16_t, int32_t,
uint32_t, int64_t, uint64_t>;
constexpr auto tsize = std::tuple_size_v<int_types>;
[]<std::size_t... Is>(std::index_sequence<Is...>) {
( // 折叠 1
[]<size_t I, std::size_t... Js>(std::integral_constant<std::size_t, I>,
std::index_sequence<Js...>)
{
( // 折叠 2:
[]<std::size_t K, std::size_t L>(
std::integral_constant<std::size_t, K>,
std::integral_constant<std::size_t, L>)
{
if constexpr(K != L) foo<std::tuple_element_t<K, int_types>,
std::tuple_element_t<L, int_types>>();
}(std::integral_constant<std::size_t, I>(),
std::integral_constant<std::size_t, Js>()),
...);
}(std::integral_constant<std::size_t, Is>(),
std::make_index_sequence<tsize>()),
...);
}(std::make_index_sequence<tsize>());
}
英文:
Here's an index based version where the inner lambda has access to the concrete indices, here L
and K
. In that you can do validation if you want to exclude calls to foo
if the indices are equal for example:
void call() {
using int_types = std::tuple<int8_t, uint8_t, int16_t, uint16_t, int32_t,
uint32_t, int64_t, uint64_t>;
constexpr auto tsize = std::tuple_size_v<int_types>;
[]<std::size_t... Is>(std::index_sequence<Is...>) {
( // fold 1
[]<size_t I, std::size_t... Js>(std::integral_constant<std::size_t, I>,
std::index_sequence<Js...>)
{
( // fold 2:
[]<std::size_t K, std::size_t L>(
std::integral_constant<std::size_t, K>,
std::integral_constant<std::size_t, L>)
{
if constexpr(K != L) foo<std::tuple_element_t<K, int_types>,
std::tuple_element_t<L, int_types>>();
}(std::integral_constant<std::size_t, I>(),
std::integral_constant<std::size_t, Js>()),
...);
}(std::integral_constant<std::size_t, Is>(),
std::make_index_sequence<tsize>()),
...);
}(std::make_index_sequence<tsize>());
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论