1

I have a problem with real-world code and have replicated the problem with the following sample code.

#include <iostream>
#include <tuple>

using namespace std;

struct Identity
{
    template <typename... T>
    static std::tuple<T...> Apply(T... val)
    {
        return std::tuple(val...);
    }
};

template <typename F, typename... T>
std::tuple<T...> Apply(T... t)
{
    return F::Apply<T...>(t...);
}

int main()
{
    const auto t = Apply<Identity>(1., 2., 3.);
    cout << std::get<0>(t);
    cout << std::get<1>(t);
    cout << std::get<2>(t);
    return 0;
}

Compilation error:

main.cpp:26:22: error: expected primary-expression before ‘...’ token
     return F::Apply<T...>(t...);
                      ^~~
main.cpp:26:22: error: expected ‘;’ before ‘...’ token
main.cpp:26:22: error: expected primary-expression before ‘...’ token

If I remove <T...> from the problematic statement, i.e. return F::Apply(t...);, and let the compiler deduce the type, it works. However, in my real world code I need to specify the types. What is the correct syntactical sugar to specific the types and satisfy the compiler?

Ted Klein Bergman
  • 9,146
  • 4
  • 29
  • 50
jcgh582
  • 839
  • 2
  • 13
  • 20

1 Answers1

5

You are missing one keyword. You need:

return F::template Apply<T...>(t...);

And it'll be fine. This error message is not the clearest one. :) You can find an explanation here if you are interested in the details: Where and why do I have to put the "template" and "typename" keywords?

simre
  • 647
  • 3
  • 9
  • 1
    I edited the answer. There is a question where you can find some information why and where do you need the template and typename keywords. – simre Jan 23 '22 at 11:23