One template specialization for multiple types

I want to make a template function that works different for int types and different for floating types. I don't want to write specializations for float, double and long double separately. I'd like to write one specialization that works for every floating type. It can't be checked in function using type_traits. How to do it?

My function:
1
2
template <typename Arg>
Arg RandomNum(const Arg n);
Last edited on
It can't be checked in function using type_traits
Why?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <typename Arg>
typename std::enable_if<std::is_floating_point<Arg>::value, Arg>::type 
RandomNum(const Arg n)
{
    std::cout << "Floating point!";
    return n;
}

template <typename Arg>
typename std::enable_if<std::is_integral<Arg>::value, Arg>::type 
RandomNum(const Arg n)
{
    std::cout << "Integer!";
    return n;
}
I thought about checking in if statement inside the function, that wouldn't work 'cuz my function creates std::uniform distibutions (int or real). I didn't even know about the way you provided. Thank you for your help, second time :).
You can use it inside function too:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<typename Arg>
Arg RandomNum_impl(const Arg n, std::true_type)
{
    std::cout << "Floating point!";
    return n;
}

template<typename Arg>
Arg RandomNum_impl(const Arg n, std::false_type)
{
    std::cout << "Int!";
    return n;
}

template <typename Arg>
Arg RandomNum(const Arg n)
{
    return RandomNum_impl(n, std::is_floating_point<Arg>{});
}
Furst approach is called SFINAE, second — tag dispatch
I meant I couldn't do something like this:

1
2
3
4
5
6
if (std::is_floating_point<Arg>::value){
std::uniform_real_distriburion<Arg> dis(0, n);
return dis(engine);
}
std::uniform_int_distribution<Arg> dis(0, n);
return dis(engine);


It would check what's the type of passed argument, and even if it was int, which wouldn't activate if statement, it would post wrong type passed to std::unform_real_distribution error.
Last edited on
> I meant I couldn't do something like this:
> It would check what's the type of passed argument, and even if it was int,
> which wouldn't activate if statement, it would post wrong type passed ...

You can, if you are desperate; use compile-time optioning instead of run-time optioning.

Though I'm not sure that uniform distribution [0,n] for integer and normal distribution (0,n) for floating point would form an intuitive interface.

1
2
3
4
5
6
7
8
9
10
template < typename T >
typename std::enable_if< std::is_arithmetic<T>::value, T >::type random( const T& n )
{
    static std::mt19937 engine{ /* seed (seq) */ } ;
    using distribution = typename std::conditional< std::is_integral<T>::value,
                                                    std::uniform_int_distribution<T>,
                                                    std::normal_distribution<T> >::type ;
    distribution dis{ T{}, n } ;
    return dis(engine) ;
}

http://coliru.stacked-crooked.com/a/b4a2071fd7290a54
Thanks. I'm going to learn a lot about C++ from this forum. Again I didn't know about this possibility. I still need to read like 600 pages of my book, so I hope that sometime I'll know C++ as good as you guys.
One advice, as you do not seems to be an absolute beginner. Get some standard library reference, for example http://en.cppreference.com/w/ , and look what standard library has to offer. No book will cover whole library, and it would be a letdown to spend several days implementing, say, class for complex arithmetic and then learning about <complex>.

For example, I doubt that your book covers this little helper: http://en.cppreference.com/w/cpp/utility/rel_ops/operator_cmp
Yeah, I'm not "an absolute beginner", so far I read 600 pages of S. Prata's book (it's not "C++ primer plus", probably you don't know it 'cuz I think it's only in Polish language (strange, right?)). Thanks for your advice, I'll do to it. And you're right one another time, I didn't know about those template operator functions. So now I need to read:
- standard library reference
- WinApi reference
- some graphics library reference (for games)
EDIT
I was mistaken, it is primer plus
Last edited on
Topic archived. No new replies allowed.