Imposing restrictions on types of template functions, without C ++ 0x concepts

Now that we know that concepts are not part of C ++ 0x, I am looking for methods to impose type restrictions in template functions.

Here are two examples:

If we want to make sure that this type is an integer, we can use:

template <class N> inline int f(const N n)
{
    if ((N)0.1 != 0)               // if type of N is floating-point
        err()

    ....
}

, if we want to make sure that this type is an unsigned integer, we can use:

template <class N> inline int f(const N n)
{
    if ((N)-1 < (N)1)              // if type of N is floating-point / signed-integer
        err()

    ....
}

I am looking for creative ways to check for additional restrictions that could lead to a crash at runtime or, better, at compile time (no concepts and no RTTI).

Any suggestions?

+3
source share
3 answers

Your checks can be handled much better at compile time using type traits.

First:

STATIC_ASSERT(std::numeric_limits<N>::is_integer)

The second:

STATIC_ASSERT(not std::numeric_limits<M>::is_signed)

Boost Concept Check Library Boost. StaticAssert.

+12

SFINAE. , GCC 4.4.1 ++ 0x:

#include <iostream>
#include <type_traits>

#define REQUIRES(...) ,class=typename std::enable_if<(__VA_ARGS__)>::type

template <typename IntType
    REQUIRES( std::is_integral<IntType>::value )
>
inline IntType f(IntType n) {
    return n;
}

int main() {
    std::cout << f( 2) << '\n';
    // std::cout << f(3.1415) << '\n'; // won't work
}

SFINAE , . , ++ 0x . ++ 98 :

template <typename IntType>
inline
typename boost::enable_if_c<(
    std::numeric_limits<IntType>::is_integer
),IntType>::type f(IntType n) {
    return n;
}

Cheers, S

+2

To easily check inheritance, you can also do

template <typename T>
class MyClass
{
private:
  static ClassA *checkIfTIsA() { return (T *)NULL; }
};
0
source

Source: https://habr.com/ru/post/1718119/


All Articles