Получить тип результата операции над числовыми типами
От: Аноним  
Дата: 24.03.10 17:19
Оценка:
Нужна метафункция ResultType<A, B>, которая выдаёт тип результата операции сложения (умножения, деления, вычитания) для значений типов A и B. Если надо, можно считать, что A и B — числовые типы.
Пример:

template <typename A, typename B>
ResultType<A, B>::Type f(A a, B b)
{
    return a + b;
}


В принципе, можно выписать все специализации. Но думаю, можно проще.
Подойдёт boost или несложный код.
Re: Получить тип результата операции над числовыми типами
От: rg45 СССР  
Дата: 25.03.10 05:18
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Нужна метафункция ResultType<A, B>, которая выдаёт тип результата операции сложения (умножения, деления, вычитания) для значений типов A и B. Если надо, можно считать, что A и B — числовые типы.


Как-то так:
template<typename> struct TypeToSize;
template<> struct TypeToSize<char>              { enum { value = 1 }; };
template<> struct TypeToSize<signed char>       { enum { value = 2 }; };
template<> struct TypeToSize<unsigned char>     { enum { value = 3 }; };
template<> struct TypeToSize<short>             { enum { value = 4 }; };
template<> struct TypeToSize<unsigned short>    { enum { value = 5 }; };
template<> struct TypeToSize<long>              { enum { value = 6 }; };
template<> struct TypeToSize<unsigned long>     { enum { value = 7 }; };
template<> struct TypeToSize<int>               { enum { value = 8 }; };
template<> struct TypeToSize<unsigned int>      { enum { value = 9 }; };
template<> struct TypeToSize<float>             { enum { value = 10 }; };
template<> struct TypeToSize<double>            { enum { value = 11 }; };

template<int> struct SizeToType;
template<> struct SizeToType<1>  { typedef char           Type; };
template<> struct SizeToType<2>  { typedef signed char    Type; };
template<> struct SizeToType<3>  { typedef unsigned char  Type; };
template<> struct SizeToType<4>  { typedef short          Type; };
template<> struct SizeToType<5>  { typedef unsigned short Type; };
template<> struct SizeToType<6>  { typedef long           Type; };
template<> struct SizeToType<7>  { typedef unsigned long  Type; };
template<> struct SizeToType<8>  { typedef int            Type; };
template<> struct SizeToType<9>  { typedef unsigned int   Type; };
template<> struct SizeToType<10> { typedef float          Type; };
template<> struct SizeToType<11> { typedef double         Type; };

template<typename A, typename B>
struct ResultType
{
  template<typename T>
  static char (&deduce(const T&))[TypeToSize<T>::value]; 
  
  typedef typename SizeToType<sizeof(deduce(A() * B()))>::Type Type;
};


Пример использования:

template <typename A, typename B>
typename ResultType<A, B>::Type sum(A a, B b)
{
  return a + b;
}

int main()
{
  std::cout << sum(0.5, 42) << std::endl;
  std::cout << sum(char(2), unsigned(3)) << std::endl;
}
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: Получить тип результата операции над числовыми типами
От: rg45 СССР  
Дата: 25.03.10 06:26
Оценка:
Здравствуйте, rg45, Вы писали:

R>Как-то так:

R>...

Эта реализация стала бы более элегантной от использования списка типов:
template<typename A, typename B>
struct ResultType
{
  DECLARE_TYPE_LIST(
    ResultTypes, 
    char, signed char, char,
    short, unsigned short,
    long, unsigned long,
    int, unsigned int,
    float, double);

  template<typename T>
  static char (&deduce(const T&))[ResultTypes::TypeIndex<T>::value + 1]; 
  
  enum { type_index = sizeof(deduce(A() * B())) - 1 };
  
  typedef typename ResultTypes::TypeByIndex<type_index>::Type Type;
};
--
Справедливость выше закона. А человечность выше справедливости.
Re: Получить тип результата операции над числовыми типами
От: 0xDEADBEEF Ниоткуда  
Дата: 26.03.10 17:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Подойдёт boost или несложный код.

Вот тебе реализация без больших извращений
//наш волшебный числовой тип
typedef boost::variant<
    unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long,
    signed char, signed short, signed int, signed long, signed long long,
    float, double, long double> number;

struct addition
{//Добавлялка. Отнималка, умножалка и делилка делаются аналогичною
    typedef number result_type;
    
    template<class A1, class A2> 
    result_type operator()(A1 const& a1, A2 const& a2) const 
    { 
        return result_type(a1 + a2); 
    }
};

int main()
{
    number n;
    
    n = boost::apply_visitor(addition(), number('\1'), number(5));
    std::cout << n.which() << ':' << n << std::endl;
    
    n = boost::apply_visitor(addition(), number('\1'), number(.5));
    std::cout << n.which() << ':' << n << std::endl;
    
    n = boost::apply_visitor(addition(), number('\1'), number(.5f));
    std::cout << n.which() << ':' << n << std::endl;

    n = boost::apply_visitor(addition(), number('\1'), number((long double).5));
    std::cout << n.which() << ':' << n << std::endl;

    n = boost::apply_visitor(addition(), number(1UL), number(2U));
    std::cout << n.which() << ':' << n << std::endl;
}
__________
16.There is no cause so right that one cannot find a fool following it.
Re: Получить тип результата операции над числовыми типами
От: bugmenot  
Дата: 04.04.10 22:03
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Нужна метафункция ResultType<A, B>, которая выдаёт тип результата операции сложения (умножения, деления, вычитания) для значений типов A и B. Если надо, можно считать, что A и B — числовые типы.

А>Пример:

А>
А>template <typename A, typename B>
А>ResultType<A, B>::Type f(A a, B b)
А>{
А>    return a + b;
А>}
А>


А>В принципе, можно выписать все специализации. Но думаю, можно проще.

А>Подойдёт boost или несложный код.

Нашёл тут: http://www.boost.org/doc/libs/1_42_0/doc/html/typeof/tuto.html
Re: Получить тип результата операции над числовыми типами
От: Юрий Жмеренецкий ICQ 380412032
Дата: 06.04.10 05:34
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Нужна метафункция ResultType<A, B>, которая выдаёт тип результата операции сложения (умножения, деления, вычитания) для значений типов A и B. Если надо, можно считать, что A и B — числовые типы.

А>Пример:

А>
А>template <typename A, typename B>
А>ResultType<A, B>::Type f(A a, B b)
А>{
А>    return a + b;
А>}
А>


А>В принципе, можно выписать все специализации. Но думаю, можно проще.

А>Подойдёт boost или несложный код.

Скоро можно будет так:

template <typename A, typename B>
auto f(A a, B b) -> decltype(a + b)
{
    return a + b;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.