Home > Blockchain >  How to get a removed-reference tuple type without using an instance in C
How to get a removed-reference tuple type without using an instance in C

Time:04-28

I wrote a test framework for testing function output (see code below).

    template <class FuncTy, class... IndexType>
    typename std::enable_if<std::tuple_size<typename function_helper<FuncTy>::arguments>::value == sizeof...(IndexType)
        and std::is_same_v<typename function_helper<FuncTy>::return_type, AnswerTy>
        and not is_member_function_pointer_v<FuncTy>, void>::type
        test(FuncTy func, IndexType... arg_indexes) {
        using function_args_tuple = typename function_helper<FuncTy>::arguments;
        using function_return_type = typename function_helper<FuncTy>::return_type;
  
        // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        function_args_tuple params;  /// error is here
        // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

        /// .....
    }

It works well for functions that do not have references in arguments.

e.g.:

  1. for fucntion int f(int x, vector<int> y); (i.e., no references in argument list), the type of params is a std::tuple<int, vector<int>>, so the params can instantiate normally with code above,
  2. but for functions like int f(int& x, vector<int>& y); (i.e., one or more references in argument list), the type of params becomes std::tuple<int&, vector<int>&>, which is not able to instantiate with code above.

The type of the tuple params is affected by argument list of a function (done with another function), the type of the tuple is undefined, so I just cannot do like this and this, since both of the solutions in the two links use a make_tuple explictly and an instantiated tuple object.

So my question is how to remove the references without instantiate the tuple. (e.g., make tuple<int&, vector<int>&> to tuple<int, vector<int>>).

Or else if there is some ways to instantiate a tuple with references in the tuple's template argument list without hard-coded make_tuple calls.

CodePudding user response:

You can get the element type of the tuple through template partial specialization and apply std::decay to those types to remove references, something like this

#include <type_traits>
#include <tuple>

template<class Tuple>
struct decay_args_tuple;

template<class... Args>
struct decay_args_tuple<std::tuple<Args...>> {
  using type = std::tuple<std::decay_t<Args>...>;
};

Then you can get a tuple of the decay argument types through the helper class

decay_args_tuple<decltype(function_args_tuple)>::type params;

Note that the argument type is still required to be default constructible.

  • Related