7

I have code something like this

template <typename T> void fun (T value)
{
    .....
    value.print ();  //Here if T is a class I want to call print (), 
                     //otherwise use printf
    .....
}

Now, to print the value, if T is a class, I want to call the print function of the object, but if T is a basic datatype, I just want to use printf.

So, how do I find if the Template type is a basic data type or a class?

jww
  • 97,681
  • 90
  • 411
  • 885
Hashken
  • 4,396
  • 7
  • 35
  • 51

4 Answers4

7

You could use std::is_class (and possibly std::is_union). The details depend on your definition of "basic type". See more on type support here.

But note that in C++ one usually overloads std::ostream& operator<<(std::ostream&, T) for printing user defined types T. This way, you do not need to worry about whether the type passed to your function template is a class or not:

template <typename T> void fun (T value)
{
    std::cout << value << "\n";
}
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
3

Recommend overloading operator<<(std::ostream&) for any type T instead of using printf(): how would you know what format specifier to use?

template <typename T> void fun (T value)
{
    .....
    std::cout << value <<  std::endl;
    .....
}

FWIW, std::is_class exists.

hmjd
  • 120,187
  • 20
  • 207
  • 252
2

If you don't have C++11 support, an alternative.

template<typename T>
class isClassT {
private:
    typedef char One;
    typedef struct { char a[2]; } Two;
    template<typename C> static One test(int C::*);
    template<typename C> static Two test(…);
public:
    enum { Yes = sizeof(isClassT<T>::test<T>(0)) == 1 };
    enum { No = !Yes };
};

A simple template for finding out if type is class type. More in C++ Templates a Complete Guide.

if (isClassT<T>::Yes) {
    std::cout << " Type is class " << std::endl;
}
stardust
  • 5,918
  • 1
  • 18
  • 20
2

I'd go with a printing helper function template/overload:

template <typename T>
void print(T const & t) { t.print(); }

template <typename U>
void print(U * p) { std::printf("%p", static_cast<void*>(p)); }
// we really an enable_if on is_object<U>::value here...

void print(char x) { std::printf("%c", x); }
void print(int x) { std::printf("%d", x); }

// etc. for all fundamental types

Then you can simply say print(value); in your code.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084