Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template struct specialization for integral/real types

I want to create validators for numbers of different kinds (integer ,floating points) e.g.:

typename number_validator<T>::type validator;

I found useful traits in the std i.e. is_integral and is_floating_point. How can I use those traits to specialize the template number_validator (it's a struct) ?

edit: I'm looking for something like this:

template<typename T, typename Enabled>
struct number_validator {};

template<typename T>
struct number_validator<T, typename enable_if<is_floating_point<T>::value, T>::type> 
//this doesn't work..
{
    typedef floating_point_validator type;
};
like image 821
Kiel Avatar asked Aug 21 '13 17:08

Kiel


3 Answers

This might be what you're looking for, i.e. tag dispatching:

template<typename T, bool = is_integral<T>::value>
struct number_validator {};

template<typename T>
struct number_validator<T, true> 
{
    typedef integral_validator type;
};

template<typename T>
struct number_validator<T, false> 
{
    typedef floating_point_validator type;
};

This assumes that you really operate on numbers, so the types are always either integral or floating point.

like image 66
emesx Avatar answered Oct 24 '22 15:10

emesx


You can do this with integer numbers:

template <typename T, bool isIntegral = std::is_integral<T>::value>
struct number_validator
{
   typedef WhatEverType type;
};

template <typename T>
struct number_validator<T, true>
{
    typedef WhatEverTypeInt type;
};

The second specialization will be chosen if it is an integer, but I don't know what to do if it is a floating point or other type.

like image 44
xorguy Avatar answered Oct 24 '22 13:10

xorguy


You don't even need those in this case, you could actually just specialize the templates like this.

template <typename T>
struct number_validator;
template <>
struct number_validator<float>;

template <>
struct number_validator<int>;

template <>
struct number_validator<double>;

This will specialize your number validator for each type, this requires you to list all the integral and floating point types. You could also do something like this:

#include <type_traits>
#include <iostream>
template<class T>
typename std::enable_if<std::is_floating_point<T>::value,T>::type func(T t) { 
    std::cout << "You got a floating point" << std::endl;
    return t;
}

template<class T>
typename std::enable_if<std::is_integral<T>::value,T>::type func(T t) { 
    std::cout << "You got an Integral" <<std::endl;
    return t;
}

int main() {
    float f = func(1.0);
    int a = func(2);
}
like image 30
aaronman Avatar answered Oct 24 '22 14:10

aaronman