This question already has an answer here:
The following code will not compile in either intel or gcc. The crux of the problem appears to be that a static method variadic template of a template class called with a parameter pack expansion is considered bad syntax on the first pass of the compiler.
template<typename T>
class foo
{
public:
template <bool do_other_thing_too, typename... ArgTypes>
static T doThing(ArgTypes... args)
{
std::vector<T> outs = { args... };
T out = 0;
for (auto V : outs) out += V;
// the actual code involves templates using SFINAE, and so must either
// be in this template's parameters or be copied, once for each value
// of the bool
if (do_other_thing_too)
{
out *= 1.5;
}
return out;
}
};
struct bar
{
int data = 3;
template<bool do_other_thing_too = true, typename T, typename...ArgTypes>
T& doThings(T& out, ArgTypes... args)
{
//the line of the code causing the problem
out = foo<T>::doThing<do_other_thing_too>(data, args...);
return out;
}
};
int main()
{
bar george;
int a = 0;
george.doThings(a, 12, 10.4, 3.2f, 4ll, 2l);
return 0;
}
It gives the following errors in gcc:
Test.cpp:27:61: error: expected ')' before '...' token
out = foo<T>::doThing<do_other_thing_too>(data, args...);
^
Test.cpp:27:65: error: parameter packs not expanded with '...':
out = foo<T>::doThing<do_other_thing_too>(data, args...);
^
Test.cpp:27:65: note: 'args'
I have done a decent bit of fiddling with the code, it will not happen if foo's T parameter is folded into foo::doThing's template i.e.
class foo
{
public:
template <typename T, bool do_other_thing_too, typename... ArgTypes>
static T doThing(ArgTypes... args)
Also, there is no problem with calling foo<int>::doThing<true>(3, 12, 10.4, 3.2f, 4ll, 2l)
directly but neither option is available in the code that spawned this. I have a solution to the problem in the short term do_other_thing_too
can be a template parameter in bar, passed by value to foo, and then I can if/else to shove it back into the template that actually needs it, but that is kinda ugly, and I really want to know what is actually causing the problem here.
Aucun commentaire:
Enregistrer un commentaire