0
votes

I'm trying to learn a bit of c++ 11 with variadic template arguments.

I want to take a list of floating point input arguments to convertTest(), then return an std::tuple of ints. I try to compile the following in g++:

template<typename ...ArgsIn, typename ...ArgsOut>
static inline std::tuple<ArgsOut...> convertTest(float nextArg, ArgsIn... remainingArgs)
{
    auto a = convertTest(remainingArgs...);
    auto b = std::make_tuple(int(nextArg));
    auto c = std::tuple_cat(a, b);

    return c;
}

static inline std::tuple<int> convertTest(float lastArgIn)
{
    return std::make_tuple((int)lastArgIn);
}

int main()
{
    auto res = convertTest(0.5f, 10.11f);
    return 0;
}

I get the following error:

 error: conversion from 'std::tuple<int, int>' to non-scalar type 'std::tuple<>' requested

I'm not sure why the return type std::tuple<ArgsOut...> would resolve to std::tuple<>. Any ideas?

I've tried making the return type auto, but I get complaints about missing trailing return types in that case.

Any ideas?

1
"I've tried making the return type auto", for that one C++11 requires trailing return type (i.e auto foo() -> returnType {/*...*/}). C++14 allows to have simply auto foo() {/*...*/} and so to deduce the return type. - Jarod42

1 Answers

4
votes

Argoutare non deducible, so become empty list. So you would have to write the function in that order instead

template<typename ... ArgsOut, typename ...ArgsIn>
static std::tuple<ArgsOut...> convertTest(float nextArg, ArgsIn... remainingArgs);

And call it

convertTest<int, int>(0.5f, 10.11f);

BTW, you may simply write it like (removing the fact that you take exclusively float)

template<typename ...Args>
auto convertTest(Args... args)
-> decltype(std::make_tuple(static_cast<int>(args)...))
{
    return std::make_tuple(static_cast<int>(args)...)
}