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))...);
}

Demo

或者,您可以更改概念以处理 const(和引用)

template<typename T>
concept IsOfTypeInt = std::same_as<std::decay_t<T>, int>;

您必须修复 ToPtrIfInt 的实现才能使 return 也正确。

Demo