Если у меня есть общая структура / класс:
template<typename T>
struct Container
{
T value;
Container(const Value& value) : value(value) { }
};
И я хочу выполнить операцию на двух из них:
template<typename T, typename U>
Container<T> operator+(const Container<T>& lhs, const Container<U>& rhs)
{
return Container<T>(lhs.value + rhs.value);
}
Проблема в том, что если lhs
имеет тип Container<int>
а также rhs
имеет тип Container<float>
тогда я получу Container<int>
назад. Но если бы я должен был сделать auto result = 2 + 2.0f
, затем result
бы типа float
, Таким образом, поведение несовместимо между встроенными типами и пользовательскими типами.
Так как бы я взял operator+
перегрузить и вернуть Container<float>
Так же, как C ++ обрабатывает арифметическое продвижение со встроенными типами?
Поскольку вы используете один из двух типов шаблона, вы рискуете вызвать приведение к результату суммы. В качестве примера, если вы случайно выбрали int
в качестве целевого типа, хотя сумма приводит к float
, он будет приведен к выбранному типу.
В любом случае, начиная с C ++ 11, вы полагаетесь на decltype
спецификатор, как в примере выше (или, по крайней мере, вы можете сделать это, если Container::T
а также Container::U
типы, для которых +
оператор определен).
Я использовал также auto
спецификатор как возвращаемое значение для operator+
, потому что он в нашем распоряжении, начиная с C ++ 14, и это действительно полезно.
Это следует из приведенного выше рабочего примера:
#include <iostream>
#include <vector>
template<typename T>
struct Container
{
T value;
Container(const T& value) : value(value) { }
};
template<typename T, typename U>
auto operator+(const Container<T>& lhs, const Container<U>& rhs)
{
return Container<decltype(lhs.value+rhs.value)>{lhs.value + rhs.value};
}
int main()
{
Container<int> c1{1};
Container<float> c2{0.5};
std::cout << (c1+c2).value << std::endl;
}
Других решений пока нет …