I have a template that takes 2 parameters. For a certain value of the first parameter, I know what the second parameter should be. I would like to have only one full definition of my template (the one that takes 2 arguments), and be able to instantiate my template supplying only one argument.
In the following example, I know that if the first template parameter is Foo1
, the second should be Foo2
. I'd like to be able to create a Someclass<Foo1,Foo2>
by writing Someclass<Foo1>
.
#include <iostream>
using namespace std;
struct Foo1 { Foo1() { cout << "Foo1 "; }};
struct Foo2 { Foo2() { cout << "Foo2 "; }};
template <typename ...Dummy> struct SomeClass;
template <typename T, typename U> struct SomeClass<T,U> {
SomeClass() {
T t;
U u;
}
};
/* Here, some one-argument specialization where if SomeClass<Foo1> is desired,
* SomeClass<Foo1, Foo2> is obtained. */
int main() {
SomeClass<Foo1, Foo2> c; //prints "Foo1 Foo2 "
SomeClass<Foo1> c2; //Should print the same thing, right now "incomplete type"
}
I guess I'm going to have to make a specialization that takes 2 arguments, the first being Foo1
, like so:
template <typename U> struct SomeClass<Foo1, U> {
SomeClass() {
Foo1 f;
U u;
}
};
But how do I make a specialization that accepts only one parameter Foo1
and results in a SomeClass<Foo1,Foo2>
?
The simplest solution for the case of a class template would probably be to define a specialization that matches the case you're interested in and have that "forward" to the specialization with the arguments you want that to map to by inheriting from it:
template <typename ...Dummy>
struct SomeClass
{
// default implementation
};
template <typename T, typename U>
struct SomeClass<T, U>
{
// case for two parameters
};
template <> struct SomeClass<Foo1> : public SomeClass<Foo1, Foo2> {};