4

I'm having a problem with this code:

#include <iostream>

using namespace std;

class A {
public:
        template<typename T, typename... Args>
        void stuff(Args... args);
};

template<typename T, typename... Args>
void A::stuff(Args... args) {
        cout << sizeof...(args) << endl;
}

template<>
void A::stuff<int>() {
        cout << "int" << endl;
}

int main() {
        A a;
        A b;

        a.stuff<char>();
        b.stuff<int>();
}

Trying to compile it, I get this error:

template-id 'stuff<int>' for 'void A::stuff()' does not match any template declaration

What am I doing wrong? I tried it without the variadicness and it worked, but how do I specialise a variadic template member function?

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249

1 Answers1

5

This looks like a bug. The problem is not limited to fully-specialized member function templates. It can be reproduced even with free-function templates as follows:

template<typename T, typename... Args>
void stuff2(Args... args);

template<typename T, typename... Args>
void stuff2(Args... args) {
    cout << sizeof...(args) << endl;
}

template<>
void stuff2<int>() {
    cout << "int" << endl;
}
int main() {}

While clang 3.2 compiles this just fine, gcc complains about:

spec.cpp:31:6: error: template-id 'stuff2' for 'void stuff2()' does not match any template declaration

There is a related SO question.

A message seems to confirm that this is indeed a bug.

Community
  • 1
  • 1
dirkgently
  • 108,024
  • 16
  • 131
  • 187
  • you can also add the current possible solution where the current problem can be solved by overloading the `stuff2()`. – iammilind Jun 17 '12 at 06:25
  • @iammilind: That doesn't fix the OP's problem (which is about member function templates and not free function templates). – dirkgently Jun 17 '12 at 06:45
  • Already upvoted the answer but, still it can be solved at [some extent](http://ideone.com/2WimQ). – iammilind Jun 17 '12 at 07:39
  • @iammilind: I think the correct expression is *to* some extent. I am afraid it may not solve the OP's issue as overload requires modifying the class definition, while specialization can be tacked on externally. – Matthieu M. Jun 17 '12 at 09:41
  • I have marked this as the answer because it answers the question, unfortunately iammilind's solution doesn't work for my situation (I can't have a default argument where the function can be called without a template argument). Hopefully this bug gets fixed quickly. Thanks. – Seth Carnegie Jun 17 '12 at 16:17
  • @SethCarnegie: Did you file one? If so, can you edit in the bug-reference? – dirkgently Jun 18 '12 at 01:37
  • @dirkgently no, I haven't filed a bug, I thought there already was one. Should I go ahead and do it? – Seth Carnegie Jun 18 '12 at 02:02
  • @SethCarnegie: I guess so. I couldn't find one. If I had I'd have put it here :) But you shouldn't trust my google-fu entirely. – dirkgently Jun 18 '12 at 02:50