Hey I normally work with Javascript and dart but I've been required to write some code in C++ for some project so I've been facing a lot of issues while writing it. I have this error that I've been trying to solve for hours with no clue I've finally decided to come here for help.
First I have this generic function that can create a tuple out of the params of the function passed into it as an argument.
template <typename R, typename... T>
tuple<T...> function_args(R (*)(T...))
{
return tuple<T...>();
}
But whenever i pass it a function that takes a vector as an argument it ends throwing an error
/tmp/ViPPynah0U.cpp: In instantiation of 'void function_args(R (*)(T ...)) [with R = int; T = {std::vector<int, std::allocator<int> >&, int}]':
/tmp/ViPPynah0U.cpp:33:18: required from here
/tmp/ViPPynah0U.cpp:23:17: error: no matching function for call to 'std::tuple<std::vector<int, std::allocator<int> >&, int>::tuple()'
And here is the complete sample code for further clarification,
#include <iostream>
#include <sstream>
#include <string>
#include <tuple>
#include <vector>
using namespace std;
int example(vector<int> &nums, int target)
{
return 0;
}
template <typename R, typename... T>
tuple<T...> function_args(R (*)(T...))
{
return tuple<T...>();
}
int main(int argc, char const *argv[])
{
auto params = function_args(example);
return 0;
}
As I've already mentioned the function works when I pass it a function that takes only primitive types as arguments the error only happens when the function takes in a vector
The issue is not with the vector, but with the fact that the function takes it as reference. You then try to initialize a tuple with a reference element here: return tuple<T...>();
- and that's not going to work. The error message basically says that: There is no default constructor for std::tuple<std::vector<int>&,int>
.
Depending on what you want to do in that case you could for example remove the reference-ness from the T
s:
template <typename R, typename... T>
auto function_args(R (*)(T...))
{
return tuple<std::remove_reference_t<T>...>();
}