Click here to Skip to main content
15,890,512 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm trying to understand c++ variadic templates.
I'm not much aware of the correct language to use to explain what I'd like to achieve, so it might be simpler if I provide a bit of code which illustrate what I'd like to achieve.

C++
#include <iostream>
#include <string>


using namespace std;

template<int ...A>
class TestTemplate1 {
public:
    string getString() {
        return "Normal";
    }
};

template<int T, int ...A>
string TestTemplate1<2, A...>::getString() {
    return "Specialized";
}


template<typename ...A>
class TestTemplate2 {

};

int main() {
    TestTemplate1<1, 2, 3, 4> t1_1;
    TestTemplate1<1, 2> t1_2;
    TestTemplate1<> t1_3;
    TestTemplate1<2> t1_4;

    TestTemplate2<> t2_1;
    TestTemplate2<int, double> t2_2;

    cout << t1_1.getString() << endl;
    cout << t1_2.getString() << endl;
    cout << t1_3.getString() << endl;
    cout << t1_4.getString() << endl;
}


This throws several errors.

- error C2333: 'TestTemplate1<>::getString' : error in function declaration; skipping function body
- error C2333: 'TestTemplate1<1,2,3,4>::getString' : error in function declaration; skipping function body
- error C2333: 'TestTemplate1<1,2>::getString' : error in function declaration; skipping function body
- error C2333: 'TestTemplate1<2>::getString' : error in function declaration; skipping function body
- error C2977: 'TestTemplate1<A...>' : too many template arguments
- error C2995: 'std::string TestTemplate1<A...>::getString(void)' : function template has already been defined
- error C3860: template argument list following class template name must list parameters in the order used in template parameter list


How can I have a specialized behavior for every `TestTemplate1<2, ...>` instances like t1_4?
Posted
Updated 6-Jun-14 0:10am
v3

The second definition is (almost) the same as the first. It is not a specialization at all.

A template specialization requires that you instantiate all the arguments. E. g.
C++
template <2, 3, 4>
string TestTemplate1() {}

You could also try a partial specialization, but I'm not sure about the syntax and have no compiler available to test that - it should be sth. like this:
C++
template <2, int ...a>
string TestTemplate1(){}


That said, I've found compilers to be lagging behind the standard when it comes to template functions. Support for classes is considerably better, and the syntax is also often clearer. therefore an alternate option would be to define a simple templated struct or class, and your declare your function as a non-templated public method.
 
Share this answer
 
Comments
[no name] 6-Jun-14 23:28pm    
5+ for the nice explaination.
Thanks Stefan_Lang, you got me looking in new directions.
I actually had to specialize the class (not just the function).

Here it is:

C++
#include <iostream>
#include <string>


using namespace std;

template<int ...A>
class TestTemplate1 {
public:
    template<int ...A>
    string getString() {
        return "Normal";
    }
};

template<int ...A>
class TestTemplate1<2, A...> { // Define a class specialization
public:
    string TestTemplate1<2, A...>::getString() {
        return "Specialized";
    }
};


template<typename ...A>
class TestTemplate2 {

};


int main() {
    TestTemplate1<1, 2, 3, 4> t1_1;
    TestTemplate1<1, 2> t1_2;
    TestTemplate1<> t1_3;
    TestTemplate1<2> t1_4;

    TestTemplate2<> t2_1;
    TestTemplate2<int, double> t2_2;

    cout << t1_1.getString() << endl;
    cout << t1_2.getString() << endl;
    cout << t1_3.getString() << endl;
    cout << t1_4.getString() << endl;
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900