First define a generic function whose purpose is to execute a function and print out the results.
In the following, func
is a reference to a function, funcName
is just the function name for terminal display, inputs
are arguments for func
.
#define TBOLD(x) "\x1B[1m" x __RST
#define TRED(x) __KRED x __RST
template<typename ...TInputs, typename TOutput>
void test_func(TOutput func(TInputs &...),
const string &funcName,
vector<tuple<TInputs...>> inputs,
const string &resultDelimiter = ", ")
{
cout << funcName << endl;
if (is_same<TOutput, bool>::value)
cout << boolalpha;
for (auto &input: inputs)
{
auto arg_idx = 0;
apply([&arg_idx](auto &&... args)
{ ((std::cout << args << (++arg_idx == sizeof...(TInputs) ? TBOLD(TRED(" : ")) : ", ")), ...); }, input);
cout << apply(func, input) << endl;
}
}
Now suppose I have the following functions,
static int func1(vector<int> &arr, int &k)
{
sort(arr.begin(),arr.end());
return arr[k];
}
template<typename Container>
static typename Container::value_type func2(Container &arr, int &k)
{
sort(arr.begin(),arr.end());
return arr[k];
}
Now the following line will compile,
test_func(func1,"func1",vector<tuple<vector<int>,int>>{make_tuple(vector<int>{3,5,1,2,4},2)})
but the following won't compile and gives a message that "could not infer template argument TOutput". In my opinion, this should have provided enough information to infer the output type TOutput
: the inputs
argument is of type vector<tuple<vector<int>,int>>
, then it should know TInputs...
is <Container, int>
, and then TOutput
is Container::value_type
.
test_func(func2,"func2",vector<tuple<vector<int>,int>>{make_tuple(vector<int>{3,5,1,2,4},2)})
If this is indeed not working, what is the right way to make the return type correctly recognized, while preserving the "generality" of this test_func
to accept functions of different arguments and output?
Aucun commentaire:
Enregistrer un commentaire