Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Nick_M_3
New Contributor I
34 Views

Weird error with variadic templates

Now, I agree that I am asking for trouble, but I find the following failure weird.  The following code:

#include <iostream>
using namespace std;

template<typename ... Pack>
void weeble(Pack ... rest, double x) {
    int y[] = {rest...};
    for (int i = 0; i < sizeof(y)/sizeof(*y); ++i) cout << y << " ";
    cout << x << endl;
}

int main () {
    weeble(123,456,789,3.1416);
}

When compiled with icpc -std=c++11 and the beta compiler, gives:

junk.cpp(12): error: no instance of function template "weeble" matches the argument list
            argument types are: (int, int, int, double)
      weeble(123,456,789,3.1416);
      ^

I cannot find anything forbidding it in C++11, and it is parsable (in theory).

If function parameter packs must be final, why did I not get an error message when the function was parsed?

0 Kudos
4 Replies
Hubert_H_Intel
Employee
34 Views

Nick,

I can reproduce the problem with the actual compiler Intel® C++ Composer XE 2013 SP1. Variadic templates should be supported. However, g++ 4.8 doesn't compile too with similar error.

Let me check.

Regards, Hubert

Nick_M_3
New Contributor I
34 Views

The gcc people pointed me at [temp.deduct.call], which indicates that a compiler is at least allowed to fail to resolve the match.  Whether that means it is required to ignore it depends on your interpretation of the wording of the standard (like so much else in C++ - sigh).

But, as with gcc, what would be useful would be a warning on the template function declaration.  I knew that I was pushing the boundary, but couldn't find anything that actually forbade that - the gcc person could, though.

Judith_W_Intel
Employee
34 Views

/*
If you look at the bottom of this paper (Issue 818):

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2010/n3079.html

You will see the restriction about funcion parameter packs being in the
final argument has been lifted.

However, this requires that a user explicitly list the arguments in
the parameter pack (template deduction will not work).

Your example is changed below. This will compile with g++ and icpc.
Judy
*/

#include <iostream>
using namespace std;

template<typename ... Pack>
void weeble(Pack ... rest, double x) {
    int y[] = {rest...};
    for (int i = 0; i < sizeof(y)/sizeof(*y); ++i) cout << y << " ";
    cout << x << endl;
}

int main () {
  weeble< int,int,int>(123,456,789,3.1416);
  return 0;
}

Nick_M_3
New Contributor I
34 Views

Thank you.  Unfortunately, that's not really a reasonable specification for my purpose :-(  I don't think that C++ can do what is wanted.