Перегрузка для беззнакового типа
От: Аноним  
Дата: 12.09.07 09:36
Оценка:
Можно ли как-то (с помощью шаблонов, частичной специализации?) перегрузить функцию для знакового и беззнаково типа?
То есть что-то вроде
// ?? template<class TInt> ??
void f(/*TInt */) {} // (1)

// ?? template<class unsigned TInt> ??
void f(/*TInt */) {} // (2)

void main()
{
    int i;
    unsigned int ui;
    f(i); // call (1) for any signed type
    f(ui); // call (2) for any unsigned type
}


Или может с классами то же самое проделать можно?
Re: Перегрузка для беззнакового типа
От: Sharp Eye Россия  
Дата: 12.09.07 09:59
Оценка: 5 (1)
Здравствуйте, Аноним, Вы писали:

А>Можно ли как-то (с помощью шаблонов, частичной специализации?) перегрузить функцию для знакового и беззнаково типа?

А>То есть что-то вроде
А>
А>// ?? template<class TInt> ??
А>void f(/*TInt */) {} // (1)

А>// ?? template<class unsigned TInt> ??
А>void f(/*TInt */) {} // (2)

А>void main()
А>{
А>    int i;
А>    unsigned int ui;
А>    f(i); // call (1) for any signed type
А>    f(ui); // call (2) for any unsigned type
А>}
А>


А>Или может с классами то же самое проделать можно?




#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/integral_constant.hpp>

template<class T>
struct is_signed_type : public boost::false_type
{};

template<class T>
struct is_unsigned_type : public boost::false_type
{};

// Специализируем...

template<>
struct is_signed_type<int> : public boost::true_type
{};

template<>
struct is_unsigned_type<unsigned int> : public boost::true_type
{};

template<class T>
typename boost::enable_if< is_signed_type<T> >::type f(T val)
{
    std::cout << val << " : signed" << std::endl;
}

template<class T>
typename boost::enable_if< is_unsigned_type<T> >::type f(T val)
{
    std::cout << val << " : unsigned" << std::endl;
}

int main(int argc, char * argv[])
{
    int i = -1;
    unsigned int j = 1;

    f(i);
    f(j);

    return 0;
}
Re: Перегрузка для беззнакового типа
От: Bell Россия  
Дата: 12.09.07 10:03
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Можно ли как-то (с помощью шаблонов, частичной специализации?) перегрузить функцию для знакового и беззнаково типа?

Обычная перегрузка не подходит? С учетом того, что встроенных типов не так уж много, это вполне приемлемое решение, ИМХО.

template<class SignedType>
f_signed_impl(SignedType i)
{
//Общая реализация для знаковых типов
}

template<class UnsignedType>
f_unsigned_impl(UnsignedTypei)
{
//Общая реализация для беззнаковых типов
}

f(unsigned char uc) { f_unsigned_impl(uc); }
f(signed char sc) { f_signed_impl(sc); }
f(char c) { f_signed_impl(c); }
...//перегрузки для остальных типов


Но можно конечно замутить и посерьезнее

template <class T>
struct is_signed;// Только объявление (использоваться могут только явные специализации)

//Вспомогательные типы
struct signed_type {};
struct unsigned_type {};

//Специализации для встроенных типов
template<>
struct is_signed<char>
{
   typedef signed_type type;
};

template<>
struct is_signed<signed char>
{
   typedef signed_type type;
};

template<>
struct is_signed<short>
{
   typedef signed_type type;
};

template<>
struct is_signed<unsigned char>
{
   typedef unsigned_type type;
};

template<>
struct is_signed<unsigned short>
{
   typedef unsigned_type type;
};


template <class T>
void f(T t, signed_type*)
{
//Общая реализация для знаковых типов
}

template <class T>
void f(T t, unsigned_type*)
{
//Общая реализация для беззнаковых типов
}

template <class T>
void f(T t)
{
   //В зависимости от типа T компилятор выберет соответствующую реализацию
   f(t, static_cast<typename is_signed<T>::type*>(0));
}

int main()
{
    short i;
    unsigned short ui;
    f(i);
    f(ui);

   return 0;
}


А>Или может с классами то же самое проделать можно?

С какими классами?
Любите книгу — источник знаний (с) М.Горький
Re[2]: Перегрузка для беззнакового типа
От: Аноним  
Дата: 12.09.07 10:51
Оценка:
Здравствуйте, Sharp Eye, Вы писали:

[]

Спасибо. Я, к сожалению, забыл сказать, что буст у нас не используется
Re[2]: Перегрузка для беззнакового типа
От: Аноним  
Дата: 12.09.07 10:58
Оценка:
Здравствуйте, Bell, Вы писали:

[]

Спасибо, остановлюсь на предложенном Вами втором варианте.
Хотелось избежать явного перечисления всех знаковых и беззнаковых типов, но, видимо, так нельзя.

А>>Или может с классами то же самое проделать можно?

B>С какими классами?
Имелся в виду как раз второй Ваш вариант
Re[3]: Перегрузка для беззнакового типа
От: Кодт Россия  
Дата: 12.09.07 12:43
Оценка: 10 (2) +1
Здравствуйте, <Аноним>, Вы писали:

А>Спасибо. Я, к сожалению, забыл сказать, что буст у нас не используется


А копипаст у вас не используется?
Там всего два файла задействовано, причём они даже целиком не нужны.

На самом деле, всё проще.
#include <limits>

// специально для бустофобов
template<bool V, class T> struct enable_if_c {};
template<class T> struct enable_if_c<true,T> { typedef T type; };




template<class T>
enable_if_c<
    std::numeric_limits<T>::is_integer &&
    std::numeric_limits<T>::is_signed,
    void >::type
    foo(T x) { std::cout << "signed integer"; }

template<class T>
enable_if_c<
    std::numeric_limits<T>::is_integer &&
    !std::numeric_limits<T>::is_signed,
    void >::type
    foo(T x) { std::cout << "unsigned integer"; }

template<class T>
enable_if_c<
    !std::numeric_limits<T>::is_integer &&
    std::numeric_limits<T>::is_specialized
    void >::type
    foo(T x) { std::cout << "float"; }

template<class T>
enable_if_c<
    !std::numeric_limits<T>::is_specialized
    void >::type
    foo(T x) { std::cout << "not a number"; }
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.