LINUX.ORG.RU

[C++] автоматическое продвижение


0

0

Есть шаблон, выписывать несколько вариантов его не охота.

Если TYPE=double или TYPE=complex, то это работает, а для TYPE=int будет ошибка.

Можно ли указать компилятору какой тип использовать?

template<class TYPE, unsigned int N>
Vector<TYPE, N> operator*(const Vector<TYPE, N> x, const double a)
{
    Vector<TYPE, N> r;
    for (unsigned int i = 0; i < N; i++)
        r.x[i] = x.x[i] * a;

    return r;
}
☆☆

Re: [C++] автоматическое продвижение

При помощи костылей только. Что бы получать более качественный еррор мессадж в бусте есть static_assert - он поможет.

theos ★★★ ()
Ответ на: Re: [C++] автоматическое продвижение от theos

Re: [C++] автоматическое продвижение

В общем, накопипастить:

template<unsigned int N>
Vector<double, N> operator*(const Vector<int, N> x, const double a)
{
    Vector<double, N> r;
    for (unsigned int i = 0; i < N; i++)
        r.x[i] = x.x[i] * a;

    return r;
}

ip1981 ☆☆ ()
Ответ на: Re: [C++] автоматическое продвижение от ip1981

Re: [C++] автоматическое продвижение

Давно не копался, но вроде в статик ассерте можно указать, что тип у шаблона ли тот либо другой.

Ну, а в простом случае - копипастить. И для случаев когда не работет делать static_assert с внятным мессджом. Если конечно не ломает буст потключать.

theos ★★★ ()

Re: [C++] автоматическое продвижение

Нагуглилось:

http://en.wikipedia.org/wiki/Template_(programming)#Class_Templates

template<typename L, typename R>
typename promote<L, R>::type max(const L &left, const R &right)
{
  // requires "::operator > (L, R)" or "L::operator > (R)"
  return left > right ? left : right;
}


Но, вроде, promote --- это фантастика из будущего?

ip1981 ☆☆ ()
Ответ на: Re: [C++] автоматическое продвижение от ip1981

Re: [C++] автоматическое продвижение

Короче, вот так:

#define MUL_VEC_NUM(rTYPE, vTYPE, aTYPE) \
template<unsigned int N> \
Vector<rTYPE, N> operator*(const Vector<vTYPE, N> v, const aTYPE a) \
{ \
    Vector<rTYPE, N> r; \
    for (unsigned int i = 0; i < N; i++) \
        r.x[i] = v.x[i] * a; \
 \
    return r; \
} \
template<unsigned int N> \
Vector<rTYPE, N> operator*(const aTYPE a, const Vector<vTYPE, N> v) \
{ \
    return v*a; \
}


#define MUL_NUM_VEC(rTYPE, vTYPE, aTYPE) 

//                рез.       вектор      чис.
MUL_VEC_NUM(gsl_complex, gsl_complex, gsl_complex)
MUL_VEC_NUM(gsl_complex, gsl_complex, double)
MUL_VEC_NUM(gsl_complex, gsl_complex, int)
MUL_VEC_NUM(gsl_complex, int,         gsl_complex)
MUL_VEC_NUM(gsl_complex, double,      gsl_complex)

MUL_VEC_NUM(double,      double,      double)
MUL_VEC_NUM(double,      double,      int)
MUL_VEC_NUM(double,      int,         double)

MUL_VEC_NUM(int,         int,         int)

ip1981 ☆☆ ()
Ответ на: Re: [C++] автоматическое продвижение от ip1981

Re: [C++] автоматическое продвижение

> MUL_VEC_NUM(double, double, double)
> MUL_VEC_NUM(double, double, int)

> MUL_VEC_NUM(double, int, double)


template<class arg1, class arg2> class Utility { typedef Result void; }; /// хотя здесь лучше statis_assert

template<> class Utility<double,double>{ typedef Result double; };
template<> class Utility<double,int>{ typedef Result double; };
template<> class Utility<int,double>{ typedef Result double; };


template<unsigned int N, class VecType, class ScalType>
Vector< Utility<VecType,ScalType>::Result >
operator* (const Vector<VecType,N> v, const ScalType a) {....}

www_linux_org_ru ★★★★★ ()

Re: [C++] автоматическое продвижение

твой подход требует дублирование => дает возможность сделать по-разному, например определить int+int=int и одновременно int-int=double

www_linux_org_ru ★★★★★ ()

Re: [C++] автоматическое продвижение

Следующая замена должна помочь: r.x[i] = TYPE(x.x[i] * a);

SSN ()

Re: [C++] автоматическое продвижение

Вдогонку: ИМХО, эффективнее будет: Vector<TYPE, N> operator*(const Vector<TYPE, N>& x, const double a)

SSN ()

труЪ-решение

#include <boost/static_assert.hpp>
#include <limits>

template<class TYPE, unsigned int N>
Vector<TYPE, N> operator*(const Vector<TYPE, N> x, const double a)
{
    BOOST_STATIC_ASSERT(!std::numeric_limits<TYPE>::is_integer);
    Vector<TYPE, N> r;
    for (unsigned int i = 0; i < N; i++)
        r.x[i] = x.x[i] * a;

    return r;
}

legolegs ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.