2015-10-24 14 views
5

Jeśli mam rodzajowe struct/klasa:Jak wypromować dwa typy szablonów dla operacji arytmetycznych, takich jak typy wbudowane?

template<typename T> 
struct Container 
{ 
    T value; 
    Container(const Value& value) : value(value) { } 
}; 

I chcę, aby wykonać operację na dwóch z nich:

template<typename T, typename U> 
Container<T> operator+(const Container<T>& lhs, const Container<U>& rhs) 
{ 
    return Container<T>(lhs.value + rhs.value); 
} 

Problem polega na tym, że jeśli lhs jest typu Container<int> i rhs jest typu Container<float>, wtedy otrzymam z powrotem Container<int>. Ale gdybym miał wykonać auto result = 2 + 2.0f, to byłby to typ result z typu float. Tak więc zachowanie jest niespójne między typami wbudowanymi a typami niestandardowymi.

W jaki sposób podjąłbym przeciążenie operator+ i zwrócę je na numer Container<float>, podobnie jak sposób, w jaki C++ obsługuje arytmetyczną promocję z wbudowanymi typami?

+0

można użyć C++ 11? –

+0

@PiotrSkotnicki Tak. – Therhang

Odpowiedz

5

Jeśli używasz jednego z dwóch typów szablonu, ryzykujesz wywołanie obsady na wyniku sumy. Na przykład, jeśli przypadkowo wybierzesz jako typ docelowy int, mimo że suma będzie miała wartość float, zostanie odrzucona do wybranego typu.

Zresztą, począwszy od C++ 11, któr polegać na decltype specyfikatora jak w powyższym przykładzie (lub przynajmniej można zrobić, jeśli Container::T i Container::U są wpisywane do których operator + jest określona).

Użyłem również specyfikatora auto jako wartości zwracanej dla operator+, ponieważ jest on do naszej dyspozycji, począwszy od C++ 14 i jest naprawdę przydatny.

Wynika przykładu wykonania wyżej wymienionego:

#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; 
} 
+1

Wygląda dobrze. Możesz uczynić go bardziej czytelnym dzięki funkcji pomocniczej 'make_container', dzięki której można wywnioskować argument szablonu:' return make_container (lhs.value + rhs.value); ' – hvd

+0

Dobrze, zostawiłbym to jako zadanie domowe ...: -) – skypjack

+0

Czy są dodatkowe koszty runtime dodane przez operację wykonaną w 'decltype'? Czy byłoby lepiej, gdybym zapisał wynik w tymczasowej zmiennej 'auto' i po prostu zrób coś w stylu' return Container (result); '? – Therhang

Powiązane problemy