std::make_tuple 在 c++20 中输入一个被操纵的 std::tuple unsing 概念
std::make_tuple with the input of a manipulated std::tuple unsing concepts in c++20
请考虑为 c++20 编写的以下 godbolted code:
#include<iostream>
#include<tuple>
template <typename T, std::size_t ...I, typename F>
void tuple_foreach_impl(T&& tuple, std::index_sequence<I...>, F&& func)
{
using dummy_array = int[];
dummy_array{(void(func(std::get<I>(tuple))), 0)..., 0};
}
template <typename T, typename F>
void tuple_foreach(T&& tuple, F&& func)
{
constexpr int size = std::tuple_size<std::remove_reference_t<T>>::value;
tuple_foreach_impl(std::forward<T>(tuple), std::make_index_sequence<size>{},
std::forward<F>(func));
}
template<typename T>
concept IsOfTypeInt = std::same_as<T, int>;
template<typename T>
concept IsNotOfTypeInt = not IsOfTypeInt<T>;
template<IsOfTypeInt T>
int* ToPtrIfInt(T& arg) { return &arg;}
template<IsNotOfTypeInt T>
T& ToPtrIfInt(T& arg) { return arg;}
template <typename... T, std::size_t... I>
auto ConvertTupleImp(const std::tuple<T...>& t, std::index_sequence<I...>)
{
return std::make_tuple(ToPtrIfInt(std::get<I>(t))...);
}
int main()
{
auto t1 = std::make_tuple(1.1,3.14159,42);
auto t2 = ConvertTupleImp(t1, std::make_index_sequence<3>());
tuple_foreach(t2, [](auto&& value)
{
std::cout << value << std::endl;
});
}
输出为:
Program returned: 0
1.1
3.14159
42
函数 ToPtrIfInt
的目的是 return 一个指向输入 int
的指针(如果输入的类型为 int
)。在任何其他情况下 ToPtrIfInt
应该 return 输入对象。正如您在输出中看到的那样,最后一个元素(值 42)没有转换为其指针。所以代码不起作用。我猜想我必须使用 ToPtrIfInt(std::forward<…>(std::get<I>(t)))...
但我无法让它工作。感谢您的帮助。
你有一个常量问题:你的元组是常量,所以你传递了 const int&
而 const int
不是 int
。删除 const 解决您的问题:
template <typename... Ts, std::size_t... Is>
auto ConvertTupleImp(std::tuple<Ts...>& t, std::index_sequence<Is...>)
{
return std::make_tuple(ToPtrIfInt(std::get<Is>(t))...);
}
或者,您可以更改概念以处理 const(和引用)
template<typename T>
concept IsOfTypeInt = std::same_as<std::decay_t<T>, int>;
您必须修复 ToPtrIfInt
的实现才能使 return 也正确。
请考虑为 c++20 编写的以下 godbolted code:
#include<iostream>
#include<tuple>
template <typename T, std::size_t ...I, typename F>
void tuple_foreach_impl(T&& tuple, std::index_sequence<I...>, F&& func)
{
using dummy_array = int[];
dummy_array{(void(func(std::get<I>(tuple))), 0)..., 0};
}
template <typename T, typename F>
void tuple_foreach(T&& tuple, F&& func)
{
constexpr int size = std::tuple_size<std::remove_reference_t<T>>::value;
tuple_foreach_impl(std::forward<T>(tuple), std::make_index_sequence<size>{},
std::forward<F>(func));
}
template<typename T>
concept IsOfTypeInt = std::same_as<T, int>;
template<typename T>
concept IsNotOfTypeInt = not IsOfTypeInt<T>;
template<IsOfTypeInt T>
int* ToPtrIfInt(T& arg) { return &arg;}
template<IsNotOfTypeInt T>
T& ToPtrIfInt(T& arg) { return arg;}
template <typename... T, std::size_t... I>
auto ConvertTupleImp(const std::tuple<T...>& t, std::index_sequence<I...>)
{
return std::make_tuple(ToPtrIfInt(std::get<I>(t))...);
}
int main()
{
auto t1 = std::make_tuple(1.1,3.14159,42);
auto t2 = ConvertTupleImp(t1, std::make_index_sequence<3>());
tuple_foreach(t2, [](auto&& value)
{
std::cout << value << std::endl;
});
}
输出为:
Program returned: 0
1.1
3.14159
42
函数 ToPtrIfInt
的目的是 return 一个指向输入 int
的指针(如果输入的类型为 int
)。在任何其他情况下 ToPtrIfInt
应该 return 输入对象。正如您在输出中看到的那样,最后一个元素(值 42)没有转换为其指针。所以代码不起作用。我猜想我必须使用 ToPtrIfInt(std::forward<…>(std::get<I>(t)))...
但我无法让它工作。感谢您的帮助。
你有一个常量问题:你的元组是常量,所以你传递了 const int&
而 const int
不是 int
。删除 const 解决您的问题:
template <typename... Ts, std::size_t... Is>
auto ConvertTupleImp(std::tuple<Ts...>& t, std::index_sequence<Is...>)
{
return std::make_tuple(ToPtrIfInt(std::get<Is>(t))...);
}
或者,您可以更改概念以处理 const(和引用)
template<typename T>
concept IsOfTypeInt = std::same_as<std::decay_t<T>, int>;
您必须修复 ToPtrIfInt
的实现才能使 return 也正确。