c++ parameters - How do I check my template class is of a specific classtype?





multiple object (8)


Instead of checking for the type use specializations. Otherwise, don't use templates.

template<class T> int foo(T a) {
      // generic implementation
}
template<> int foo(SpecialType a) {
  // will be selected by compiler 
}

SpecialType x;
OtherType y;
foo(x); // calls second, specialized version
foo(y); // calls generic version

In my template-ized function, I'm trying to check the type T is of a specific type. How would I do that?

p/s I knew the template specification way but I don't want to do that.

template<class T> int foo(T a) {
  // check if T of type, say, String?
}

Thanks!




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

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, i.e., 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




I suppose you could use the std::type_info returned by the typeid operator




Instead of checking for the type use specializations. Otherwise, don't use templates.

template<class T> int foo(T a) {
      // generic implementation
}
template<> int foo(SpecialType a) {
  // will be selected by compiler 
}

SpecialType x;
OtherType y;
foo(x); // calls second, specialized version
foo(y); // calls generic version



How do I check my template class is of a specific classtype?

I suppose you could use the std::type_info returned by the typeid operator




If you don't care about compile-time, you may use boost::is_same.

bool isString = boost::is_same<T, std::string>::value;

As of C++11, this is now part of the standard library

bool isString = std::is_same<T, std::string>::value



If you don't care about compile-time, you may use boost::is_same.

bool isString = boost::is_same<T, std::string>::value;

As of C++11, this is now part of the standard library

bool isString = std::is_same<T, std::string>::value



Have you tried passing -funroll-loops -fprefetch-loop-arrays to GCC?

I get the following results with these additional optimizations:

[1829] /tmp/so_25078285 $ cat /proc/cpuinfo |grep CPU|head -n1
model name      : Intel(R) Core(TM) i3-3225 CPU @ 3.30GHz
[1829] /tmp/so_25078285 $ g++ --version|head -n1
g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3

[1829] /tmp/so_25078285 $ g++ -O3 -march=native -std=c++11 test.cpp -o test_o3
[1829] /tmp/so_25078285 $ g++ -O3 -march=native -funroll-loops -fprefetch-loop-arrays -std=c++11     test.cpp -o test_o3_unroll_loops__and__prefetch_loop_arrays

[1829] /tmp/so_25078285 $ ./test_o3 1
unsigned        41959360000     0.595 sec       17.6231 GB/s
uint64_t        41959360000     0.898626 sec    11.6687 GB/s

[1829] /tmp/so_25078285 $ ./test_o3_unroll_loops__and__prefetch_loop_arrays 1
unsigned        41959360000     0.618222 sec    16.9612 GB/s
uint64_t        41959360000     0.407304 sec    25.7443 GB/s




c++ templates