This program adds nested vectors, but does not promote the types correctly. I think std::plus needs to take in T1 or T2 depending on basic type promotion rules. The original problem is in this post (decltype does not resolve nested vectors. How can I use templates for nested vectors?).
main.cpp
#include <algorithm>
#include <iostream>
#include <vector>
template<typename T1>
std::ostream& operator<<(std::ostream& stream, std::vector<T1> r){
if(r.size() == 0){
return stream;
}
else{
stream << "(";
for(int i = 0; i < r.size(); i++){
if(i < (r.size() - 1)){
stream << r[i] << ", ";
}
else{
stream << r[i] << ")";
}
}
}
return stream;
};
template <typename T1, typename T2>
struct Add : std::plus<T1> { };//<-Here T1 or T2 depending on their types.
template <typename T1, typename T2>
struct Add<std::vector<T1>, std::vector<T2>>
{
auto operator()(const std::vector<T1>& l, const std::vector<T2>& r)
-> std::vector<decltype(Add<T1,T2>{}(l[0], r[0]))>
{
using type = decltype(Add<T1,T2>{}(l[0], r[0]));
std::vector<type> ans;
if(l.size() == std::max(l.size(),r.size()))
std::transform(r.begin(), r.end(), l.begin(), std::back_inserter(ans), Add<T1,T2>{});
else
std::transform(l.begin(), l.end(), r.begin(), std::back_inserter(ans), Add<T1,T2>{});
return ans;
};
};
template <typename T1, typename T2>
auto operator+(const std::vector<T1>& lhs, const std::vector<T2>& rhs)
-> decltype(Add<std::vector<T1>, std::vector<T2>>{}(lhs, rhs))
{
return Add<std::vector<T1>, std::vector<T2>>{}(lhs, rhs);
}
int main(){
std::vector<int> e = {1};
std::vector<double> q = {1.5};
//Incorrect result = 2
std::cout << (e + q) << std::endl;
//Correct result = 2.5
std::cout << (q + e) << std::endl;
return 0;
}
There are two issues in your code (that I got wrong in my answer to your original question). The first, as mentioned by vsoftco is using
std::common_type
for the base case.The second is a simple error. Consider this if statement:
Add<T1,T2>::operator()
, in the partial specialization case, takes two arguments: astd::vector<T1>
and astd::vector<T2>
, in that order. But in the two branches of theif
statement, we're actually calling them in different orders. In thetrue
branch, we're calling them in the REVERSE order, so just have to invert the ordering in the template:Should actually just remove the
if
-statement altogether so that the specialization case is now: