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;
}
☆☆

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

theos ★★★
()
Ответ на: комментарий от theos

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

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 ☆☆
() автор топика
Ответ на: комментарий от ip1981

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

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

theos ★★★
()
Ответ на: комментарий от ip1981

Ага этот С++0х будет ещё неизвестно когда, хотя вот может эту фичу gcc уже и умеет.

theos ★★★
()
Ответ на: комментарий от ip1981

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

#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 ☆☆
() автор топика
Ответ на: комментарий от ip1981

> 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 ★★★★★
()

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

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Reset

> Анекдоты на C++: генерация шаблонов с помощью макросов :)

в тяжелых случаях и *это* тоже пригодится :-)

www_linux_org_ru ★★★★★
()

Вдогонку: ИМХО, эффективнее будет: 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 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.