Выведите тип возврата оператора / функции для шаблонов - PullRequest
9 голосов
/ 30 сентября 2010

Возможно ли что-то подобное?

// We can even assume T and U are native C++ types
template<typename T, typename U>
magically_deduce_return_type_of(T * U) my_mul() { return T * U; }

Или кто-нибудь должен будет взломать структуру return_type и специализировать ее для каждой пары нативных типов?

Ответы [ 5 ]

12 голосов
/ 30 сентября 2010

Слышно decltype?

В C++0x вы можете сделать

template<class T, class U>
auto mul(T x, U y) -> decltype(x*y)
{
    return x*y;
}
8 голосов
/ 26 сентября 2011

Вы можете сделать это в не C++0x коде:

template<typename T, typename U> class Mul
{
  T t_;
  U u_;
public:
  Mul(const T& t, const U& u): t_(t), u_(u) {}
  template <class R>
  operator R ()
  {
    return t_ * u_;
  }
};

template<typename T, typename U>
Mul<T, U> mul(const T& t, const U& u)
{
  return Mul<T, U>(t, u);
}

Использование: char t = 3; короткий u = 4; int r = mul (t, u);

Здесь у нас два вывода типа. Мы неявно объявляем тип возврата по использованию, а не точно decltype (T * U)

2 голосов
/ 30 сентября 2010

Я использую Visual Studio 2008, поэтому мне пришлось придумать способ, отличный от C ++ 0x. Я закончил тем, что делал что-то подобное.

template<typename T> struct type_precedence { static const int value = -1; };
template< > struct type_precedence<long double> { static const int value = 0; };
template< > struct type_precedence<double> { static const int value = 1; };
template< > struct type_precedence<float> { static const int value = 2; };
template< > struct type_precedence<unsigned long long> { static const int value = 3; };
template< > struct type_precedence<long long> { static const int value = 4; };
template< > struct type_precedence<unsigned long> { static const int value = 5; };
template< > struct type_precedence<long> { static const int value = 6; };
template< > struct type_precedence<unsigned int> { static const int value = 7; };
template< > struct type_precedence<int> { static const int value = 8; };
template< > struct type_precedence<unsigned short> { static const int value = 9; };
template< > struct type_precedence<short> { static const int value = 10; };
template< > struct type_precedence<unsigned char> { static const int value = 11; };
template< > struct type_precedence<char> { static const int value = 12; };
template< > struct type_precedence<bool> { static const int value = 13; };

/////////////////////////////////////////////////////////////////////////////////////////

template<typename T, typename U, bool t_precedent = ((type_precedence<T>::value) <= (type_precedence<U>::value))>
struct precedent_type { 
    typedef T t; 
};
template<typename T, typename U>
struct precedent_type<T,U,false> { 
    typedef U t;
};

/////////////////////////////////////////////////////////////////////////////////////////

template<typename T, typename U>
typename precedent_type<T,U>::t my_mul() { return T * U; }

РЕДАКТИРОВАТЬ: Вот пример - я делаю это для умножения векторов. Это выглядит примерно так:

template<int N, typename T, typename U>
vec<N,typename precedent_type<T,U>::t> operator *(const vec<N,T>& v1,const vec<N,U>& v2) {
    ...
}

...

double3 = float3 * double3;
float4 = float4 * int4;
etc.
1 голос
/ 30 сентября 2010
0 голосов
/ 30 сентября 2010

до C ++ 0x

Я не знаю точно, чего вы хотите достичь, поэтому:

template<typename T, typename U>
void my_mul(T t, U u, bool& overflow) 
{
    my_mul_impl(t*u, overflow);
}

template<typename TmultU>
void my_mul_impl(TmultU mult, bool& overflow)
{
    //here you know the type and can do something meta-weird :)
    if(mult > type_traits<TmultU>::max_allowed_in_my_cool_program())
       overflow = true;
}

Есть больше

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...