将元组类型转换为衰减类型

convert tuple types to decay types

我正在玩 C++17,我有 std::tupleconst &T 类型。例如:

template <typename... members>
auto make_cr_tuple(members const &...args) -> decltype(auto) {
    return std::make_tuple(std::cref(args)...);
}

int main() {
    std::string s;
    int i = 0;
    auto crt = make_cr_tuple(s, i); // std::tuple<const std::string &, const int &>
}

我想要一种方法来声明每个值类型的元组,删除 const 和引用限定符。例如,可能是这样的:

    using decayed = decayed_tuple<decltype(crt)>::type

我想我可能会使用这样的东西,但这还不够。

template <typename T>
struct decayed_tuple {
    using type = decltype(std::apply(std::make_tuple, T{}));
};

显然这不起作用,因为 make_tuple 是一个未解析的重载函数。

我确实需要 std::make_tuple<???>,但我不知道如何将类型从 T 获取到模板包。请注意,我假设 T 在这里是默认可构造的。

对于 Boost.Mp11,这是一个简短的一行(一如既往):

template <typename Tuple>
using decayed_tuple = mp_transform<std::decay_t, Tuple>;

也许你可以声明(不需要定义)一个函数如下

template <typename ... Ts>
constexpr auto decay_types (std::tuple<Ts...> const &)
   -> std::tuple<std::remove_cv_t<std::remove_reference_t<Ts>>...>;

并通过 std::declval()decltype() 使用它。

也许你也可以添加一个using别名来简化工作

template <typename T>
using decay_tuple = decltype(decay_types(std::declval<T>()));

一个完整的例子

#include <tuple>
#include <type_traits>

template <typename ... Ts>
constexpr auto decay_types (std::tuple<Ts...> const &)
   -> std::tuple<std::remove_cv_t<std::remove_reference_t<Ts>>...>;

template <typename T>
using decay_tuple = decltype(decay_types(std::declval<T>()));

int main()
 {
   using T1 = std::tuple<int const &, long const &, long long const &>;
   using T2 = decay_tuple<T1>;

   static_assert( std::is_same_v<T2, std::tuple<int, long, long long>>, "!");
 }