简体   繁体   中英

How can i identify if a template parameter argument is instance of another class in a struct within template? C++

I have a .h file with all my templates in it and a .cpp file with my main.

Part of .h templates:

   template<int N, int P>
    struct BOUND {
        static inline int eval(int v) {
            //...
            return 1; 
        };
    };

    template<class K>
    struct VAL_x {
        static inline int eval(int v) {
            //...
            return 1;
        };
    };

    template<int L, class K>
    struct LIT {
        static inline int eval(int v) {
            //...
            return 1;
        };
    };

    template<class A, class B, class K>
    struct ADD {
        static inline int comp_b(int v){
            // HERE check if class A is LIT  or VAL_x
            //...
            return 2;
        };
    };

Here is how I call in my main() this template:

int main() {

    typedef ADD<VAL_x<BOUND<2,3> >, LIT<2, BOUND<2,3> >, BOUND<2,3> > FORM;
    FORM exec_form;

    int y = 2;

    int bounds = exec_form.comp_b(y);

    return 0;
}

How can I know in ADD::comp() function of my struct , if an argument that was passed is instance of a specific class (eg LIT<> )? Those arguments can be passed in any order (eg all arguments could be LIT , or only the second one)

NOTE : there are also other structs apart from VAL_x , LIT , BOUND and ADD .

Option #1

Introduce a separate trait for each class template of interest (C++03 doesn't help here much).

template <bool B> struct bool_constant { static const bool value = B; };
template <bool B> const bool bool_constant<B>::value;

template <typename T>   struct is_LIT : bool_constant<false> {};
template <int L, int M> struct is_LIT<LIT<L, M> > : bool_constant<true> {};

template <typename T> struct is_VAL_x : bool_constant<false> {};
template <int K>      struct is_VAL_x<VAL_x<K> > : bool_constant<true> {};

template <class A, class B>
struct ADD 
{
    static inline int comp_b(int v)
    {
        if (is_LIT<A>::value && is_VAL_x<B>::value)
        {

        }

        return 2;
    }
};

DEMO

Option #2

Use a generic custom trait, whose specialization detects if the type passed is an instantiation of the specified template-template parameter (it is if the specialization matches, ie, T is an instantiation of class template X ):

template <template <int> class X, typename T>
struct is_template { static const bool value = false; };

template <template <int> class X, int N>
struct is_template<X, X<N> > { static const bool value = true; };

template <typename A, typename B>
struct ADD 
{
    static inline int comp_b(int v)
    {
        if (is_template<VAL_x, A>::value && is_template<LIT, B>::value)
        {
        }

        return 2;
    }
};

DEMO 2

Option #3

Use tag-dispatching, possibly add overloads for other class templates that return true / false , making it similar to Option #1. This solution also relies on overload resolution, that prefers more specialized function templates over those less constrained/generic.

template <typename T> struct tag {};

template <typename A, typename B>
struct ADD 
{
    static inline int comp_b(int v)
    {
        return comp_b(v, tag<A>(), tag<B>());
    }

    template <int M, int N>
    static inline int comp_b(int v, tag<LIT<M> >, tag<VAL_x<N> >)
    {
        return 1;
    }

    template <typename T, typename U>
    static inline int comp_b(int v, tag<T>, tag<U>)
    {
        return 2;
    }
};

DEMO 3

You could do it like this:

#include <typeinfo>
...
template<class A, class B>
struct ADD {

    static inline int comp_b(int v){
        // HERE check if class A is LIT  or VAL_x
        std::cout << ( typeid(A)==typeid(VAL_x) ) << '\n';
        return 2;
    };
};

where I am using std::type_info , which will print 1, for true evaluation.

Or, with , you could do:

#include <type_traits>
...
if (std::is_same<A, VAL_x>::value)
    std::cout << "they are same!\n";

However, you could overload a function or such. Make sure you read this: How do I check my template class is of a specific classtype? and this How to check for the type of a template parameter?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM