samedi 27 avril 2019

Could not infer template argument when using "typename Container::value_type" as the return value

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