My code:
enum class list{one, two};
template <list T> class Base;
template <> class Base <list::one>{
A a{list::one};
B b{list::one};
C c{list::one};
};
template <> class Base <list::two>{
B b{list::two};
C c{list::two};
D d{list::two};
};
But I would like to avoid duplicating code, and use reference to specialization value, like this:
template <> class Base <list::one>{
A a{T};
B b{T};
C c{T};
};
template <> class Base <list::two>{
B b{T};
C c{T};
D d{T};
};
I can make sludge temporary variable, but does not look good too:
template <> class Base <list::one>{
list T = list::one;
A a{T};
B b{T};
C c{T};
};
Is there are any way to get reference to template specialization value?
In the following example I'm using SFINAE to make T
available in the definition of Base
. Specifically I have done the following:
T
(and specifying the second dummy type parameter),T
is equal to list::one
and list::two
in the two specializations, via std::enable_if_t
.#include <iostream>
#include <type_traits>
enum class list{one, two};
// to make the code compile
class A { public: A(list) {} };
class B { public: B(list) {} };
class C { public: C(list) {} };
class D { public: D(list) {} };
// primary template (second param's sole purpose is to allow partial spec.)
template <list T, typename = void>
class Base;
// partial specialization #1
template <list T>
class Base <T, std::enable_if_t<T == list::one>>{
A a{T};
B b{T};
C c{T};
public:
Base() { std::cout << "list::one\n"; }
};
// partial specialization #2
template <list T>
class Base <T, std::enable_if_t<T == list::two>>{
B b{T};
C c{T};
D d{T};
public:
Base() { std::cout << "list::two\n"; }
};
int main() {
Base<list::one> o;
Base<list::two> t;
}
This is a pretty standard way of using taking advantage of SFINAE via std::enable_if
. Similar examples can be found on cppreference page on std::enable_if
, where the last example (the one with the first comment // primary template
) resambles the code above.