Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
206 views
Welcome To Ask or Share your Answers For Others

1 Answer

In the following example I'm using SFINAE to make T available in the definition of Base. Specifically I have done the following:

  • added one dummy type parameter to the primary template,
  • made the two specialization partial by not specifying the parameter T (and specifying the second dummy type parameter),
  • specified the second dummy type parameter enforcing that 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
"; }
};

// 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
"; }
};

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...