Search code examples
c++template-meta-programmingstatic-assert

Obtain original struct/class name during C++ template instantiation


template<typename T> struct S {};
template<typename T> struct R {};

int main() {
  typedef S<double> s1;
  typedef S<int> s2;
  typedef R<int> s3;
  static_assert(xxx<s1, s2>::value,
                "No, assertion must not be raised");
  static_assert(xxx<s2, s3>::value,
                "Yes, assertion must be raised");
}

So, I want xxx<s1, s2>::value to return true while xxx<s2, s3>::value to return false during compile-time.

Is the existence of xxx impossible in C++? Or, is the existence of xxx theoretically possible in C++ but possibly no one has done it yet?


Solution

  • Use two specialisations​ that use template template parameters to perform this "matching":

    template<
      typename T,
      typename V>
    struct xxx;
    
    template<
     template <class> class A,
     template <class> class B,
     typename X,
     typename Y>
    struct xxx<A<X>, B<Y>> {
      static constexpr const int value = false;
    };
    
    
    template<
     template <class> class U,
     typename X,
     typename Y>
    struct xxx<U<X>, U<Y>> {
      static constexpr const int value = true;
    };
    

    With your code on ideone

    Note: For it to be a real type trait you should not set value manually, but derive from std::integral_constant (std::true_type or std::false_type). Above is just a quick mockup I did on my phone.