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
.
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;
}
};
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;
}
};
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;
}
};
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 c++11 , 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.