Я реализовал свой собственный класс единиц СИ. При использовании арифметических операций полученный SI-блок может измениться. Например: (метр/секунда)/метр = 1/сек.C++ шаблон возвращаемого типа в зависимости от аргументов шаблона?
Теперь я также создал простой класс 3D Vector. Этот вектор должен быть общим, а также использоваться с моим классом единиц СИ. Поэтому я реализовал простой оператор разделения. Смотрите следующий код:
// Determine result type of Lhs/Rhs:
template < class Lhs, class Rhs >
struct TV3TypeV3Div { typedef BOOST_TYPEOF(Lhs()/Rhs()) type; };
// Vector/Vector:
template < class Lhs, class Rhs >
RobotTools::DataTypes::TV3Type< typename TV3TypeV3Div< Lhs, Rhs >::type > operator/(const RobotTools::DataTypes::TV3Type<Lhs>& lhs,
const RobotTools::DataTypes::TV3Type<Rhs>& rhs)
{
// do something useful
return RobotTools::DataTypes::TV3Type< typename TV3TypeV3Div< Lhs, Rhs >::type >(0, 0, 0);
}
// Vector/Vector
RobotTools::DataTypes::TV3Type<Tools::DataTypes::Length> vl;
vl/vl; // Ok this works
во время компиляции правильного типа возврата будет определяться с помощью TV3TypeV3Div-структуру. Это работает.
Теперь я хочу расширить операторы. Я также хочу рассчитать векторы со скалярными типами. Поэтому я написал этого оператора:
// Vector/Scalar
template < class Lhs, class Rhs >
RobotTools::DataTypes::TV3Type< typename TV3TypeV3Div< Lhs, Rhs >::type > operator/(const RobotTools::DataTypes::TV3Type<Lhs>& lhs,
const Rhs& rhs)
{
// do something useful
return RobotTools::DataTypes::TV3Type< typename TV3TypeV3Div< Lhs, Tools::DataTypes::Length >::type >(0, 0, 0);
}
// Vector/Scalar
RobotTools::DataTypes::TV3Type<Tools::DataTypes::Length> vl;
Tools::DataTypes::Length sl;
vl/sl; // Ok nice it works too
Пока все хорошо. Проблема в том, что когда я определяю второй оператор (Vector/Scalar), этот оператор настолько обобщен, что компилятор хочет использовать его также для векторного/векторного деления. Но это не удается, потому что LHS()/Rhs() с:
LHS = Инструменты :: Datatypes :: Длина и RHS = RobotTools :: Datatypes :: TV3Type
не определен. Это правильно, и я понимаю данную ошибку. Я не понимаю, что компилятор НЕ использует оператор Vector/Vector.
- Есть ли возможность дать компилятору подсказку, какой оператор использовать?
- Есть ли возможность переписать операторов для полного заполнения моего требования?
Я смущен! Это действительно работает. Я потратил целый день на это простое решение :) Не могли бы вы объяснить это немного больше. Я не вижу волшебства. – Mark
Я добавил несколько объяснений. –
Спасибо n.m. за великое объяснение. Тем временем я пробовал ваш подход в рамках моего первоначального проекта. Но он не работает в нескольких местах с кодом ошибки InvalidDivision .... Я думаю, будет непросто обновить весь проект. Так что, может быть, мне нужна магия SFINAE, возможно, используя boost? Есть идеи ? – Mark