Информация:Возврат типа функции шаблона
В настоящее время я пытаюсь узнать шаблон метапрограммирования (следуя this book). Один из полезных примеров, которые они дают, - это анализ размеров. Я реализовал его, как в книге, и все было в порядке; see here.
Моя проблема, однако, я хочу использовать структуру анализа размеров со смешанными типами. Под этим я имею в виду, что вы могли бы сказать скаляр с размерами массы, умножающими вектор с размерами ускорения, чтобы дать векторную силу. Как показано в ссылке, они работают только с одним типом T
для ввода и вывода всех операций.
У меня есть 3-вектор класс, который имеет все необходимые операции для умножения/деления на скаляры и т.д., так что я хотел бы сделать что-то вроде
quantity<double,mass> m(1.0);
quantity<vect,acceleration> a(vect(0.0,0.0,-9.81));
quantity<vect,force> f = m*a;
Первая попытка:
Чтобы добиться этого, я попытался использовать примеры из книги, чтобы обрабатывать два разных типа в качестве входных данных для operator*
и operator/
, однако я ударил стену, когда дело доходит до типа возврата.
Я знаю, что здесь возвращаемый тип double * vect
является vect
, но если они наоборот vect * double
это еще vect
. Хуже; в принципе тип возврата может быть любым. Поэтому я хочу способ продлить operator*
на что-то вроде
template<class T1, class T2, class Dim1, class Dim2>
quantity<X, typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
operator*(const quantity<T1,Dim1>& q1, const quantity<T2,Dim2>& q2)
{
return quantity<X,
typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
(q1.value()*q2.value());
}
где X
является тип возвращаемого q1.value()*q2.value()
и выводится во время компиляции. Я попробовал просто добавить еще один шаблонный класс T3
к подписи и вернуть его T3
, но, похоже, он не может определить, что должно быть T3
.
Вторая попытка:
Далее я попытался использовать decltype
следующим
template<class T1, class T2>
struct return_type
{
auto mult_f(const T1& a, const T2& b)->decltype(a*b){return a*b;}
typedef decltype(mult_f) type;
};
template<class T1, class T2, class Dim1, class Dim2>
quantity<typename return_type<T1,T2>::type, typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
operator*(const quantity<T1,Dim1>& q1, const quantity<T2,Dim2>& q2)
{
return quantity<typename return_type<T1,T2>::type,
typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
(q1.value()*q2.value());
}
Однако это бросает множество непонятных ошибок компилятора.
Вопрос:
Мой вопрос тогда, я использую decltype
в правильном пути, но не хватает какой-то синтаксис, например, a typename
спецификатор где-нибудь? Или; возможно ли это сделать так, и если нет, то как можно вычислить возвращаемый тип функции?
Спасибо.
Да, я могу сказать из вывода компилятора, что получаю целую подпись функции. Я не знаю, почему я так много усложнял, ваш пример компилируется отлично :) Требование конструктора по умолчанию для меня здесь не проблема. – Dan
@ Dan: обратите внимание, что книга была написана до появления C++ 11 и 'decltype' /' auto', что сделало вещи ** намного сложнее. –
Заменить 'decltype (T1() * T2())' с 'decltype (std :: declval() * std :: declval ())', и вы больше не требуете конструктивности по умолчанию. –
ildjarn