Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to get a removed-reference tuple type without using an instance in C++

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.:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  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.

>Solution :

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... Args>
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 the tuple of the decay argument types through the helper class

decay_args_tuple<decltype(function_args_tuple)>::type params;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading