#c
#c
Вопрос:
Я написал номер класса, который содержит только один атрибут: значение T . В настоящее время я изучаю шаблоны, поэтому T — это тип данных. Чего я хочу добиться, так это выполнения следующего вида вычислений.
Number<int>(2) Number<double>(1.2)
То, что у меня есть до сих пор, может выполнять операцию, но она завершается неудачей при наличии двух разных типов данных. До сих пор я писал это:
//class template
template<class T>
class Number
{
public:
T value;
Number(T num1)
{
value = num1;
}
Number<T> operator ( const Number<T> amp;other) const
{
return Number<decltype(value other.value)> (value other.value);
}
};
Он выполняет арифметическую операцию только тогда, когда типы данных совпадают:
Вопросы:
- Почему программа работает только с одними и теми же типами данных?
За часть этого я могу ответить сам. Я использую строку:
Number<T> operator ( const Number<T> amp;other) const
Итак, если левая сторона имеет тип int
. Каждый T становится an int
. Я не знаю, как мне нужно это изменить, не получая ошибки.
- Что мне нужно исправить, чтобы выполнять вычисления с разными типами данных?
Редактировать:
Ограничение заключается в том, что шаблон может содержать только один аргумент типа
Комментарии:
1. Вам нужно объявить operator , который принимает разные типы данных с левой и правой стороны, вместо operator, который принимает число<T> с обеих сторон.
2. Вам нужно что-то вроде этого:
template<class T, class U> Number<std::common_type_t<T, U>> operator (const Number<T>amp;, const Number<U>amp;)
. Предпочитаюoperator
определяться как свободная функция (возможноfriend
, одна).3. на самом деле можно использовать тип возврата auto плюс завершающий, чтобы вычесть тип, выполненный во время компиляции. например
auto operator (const Number<T> amp;, const Number<S> amp;) -> Number<decltype(a.value b.value)>;
, или, если значение является частным,a.value b.value
может быть заменено наstd::declval<T>() std::declval<S>()
. Более аккуратный,std::common_type::type(c 11)/std::common_type_t(c 14)
также может быть использован.4. @SHP откуда берутся переменные a и b? Я забыл упомянуть, что ограничением является то, что я могу использовать только один аргумент типа для шаблона. В результате я больше не могу использовать: const Number<S> . Что бы вы посоветовали мне сделать? Спасибо за ответ!
5. @Nadine Функция друга шаблона не изменяет способ объявления вашего класса, у вас все еще есть число<T1> a; и число<T2> b; параметр two template используется только в функции a b.
Ответ №1:
Помимо объявления оператора-друга с двумя предлагаемыми параметрами шаблона, вы также можете разместить дополнительный шаблон для функции-члена operator , что позволяет выполнять приведение plus .
template<typename T>
class Number
{
public:
T value;
Number(const Tamp;num1)
{
value = num1;
}
template <typename X> auto operator ( const Number<X> amp;other) const
{
auto c = this->value other.value;
return Number<decltype(c)> ( c );
}
};
#include <iostream>
int main()
{
Number<int> n{2};
Number<double> a{3.4};
std::cout << (a n).value << std::endl;
}
Или вы можете использовать функцию друга (я думаю, что это более символично).
template<typename T>
class Number
{
public:
T value;
Number(T num1)
{
value = num1;
}
Numberamp; operator =( const Number<T> amp;other)
{
this->value = other.value;
return *this;
}
};
template <typename T1,typename T2> auto operator (const Number<T1>amp;a, const Number<T2>amp;b)
{
auto c = a.value b.value;
return Number<decltype(c)>( c );
}
Ответ №2:
#include <iostream>
#include <type_traits>
template <typename T>
struct Number {
Number(T _value = T(0)) : value(_value) {}
template <typename S>
Number(const Number<S>amp; n) : value(n.value) {}
T value;
template <typename S>
friend Number<S> operator (const Number<S>amp; a, const Number<S>amp; b);
};
template <typename S>
Number<S> operator (const Number<S>amp; a, const Number<S>amp; b) {
return Number<S>{a.value b.value};
}
int main() {
std::cout << operator <typename std::common_type<int, double>::type>(Number<int>{1}, Number<double>{1.2}).value << std::endl;
return 0;
}
это реализация c 11. operator содержит ровно один аргумент. Я надеюсь, что это то, что вы хотите.