I'm working on a class template, and I would like to be able to compare a template variable to a data type, rather than a value, and have a template function return a varying default value. Something like this:
1 2 3 4 5 6 7 8
template <class TYPE>
func<TYPE>(TYPE temp)
{
if (temp is an integer?) return 0;
elseif (temp is a char?) return' ';
elseif (temp is a double?) return 0;
etc..
}
The reason I'm doing this is because the class template is being used to implement a linked stack, and if the stack is empty, I want to be able to return a default value instead of crashing the program with assert or a badalloc error, no matter what type of data is in the stack. I only need to know if what my main idea is possible, because if not I know how to implement the stack in other ways.
> if the stack is empty, I want to be able to return a default value
1 2 3 4
template < typename T > T default_value()
{
return T{} ; // empty initialiser: return a value initialised T
}
If value initialisation (zero-initialisation or default construction) is not appropriate for some types, something like this:
1 2 3 4 5 6 7 8 9 10 11
#include <type_traits>
// default value is space for char
template < typename T >
typename std::enable_if< std::is_same<T,char>::value, T >::type default_value()
{ return' ' ; }
// default value is a value initialised object for types other than char
template < typename T >
typename std::enable_if< !std::is_same<T,char>::value, T >::type default_value()
{ return T{} ; }
If an object of type T will be passed as the argument, simple function overloading would be adequate:
1 2 3 4 5
// default value is space for char
char default_value( char ) { return' ' ; }
// default value is a value initialised object for types other than char
template < typename T > T default_value( T ) { return T{} ; }
Note that this is not good code, when the static type of temp is known from a template type parameter:
1 2
if ( typeid( temp ) == typeid( int ) ) { /* ... */ }
elseif ...