I have a class templated with typename T. It contains a function,
template
myClass operator+(myClass
The compiler on overload resolution fails to find a right candidate for operator+ because T is already being deducted to double and literal 5 is an integer. Solution:
template <typename T1, typename T2, size_t a>
myClass<T1,a> operator+(myClass<T1,a> lhs, const T2& rhs) {
return lhs += T1(rhs);
}
When you are using template argument deduction, all deductions for one template parameter must have the same result.
In your case, the two deductions for T produce double and int, which are not the same, and so deduction fails.
What you can do is only use one function argument for template argument deduction, and make the other one undeduced:
template <typename T, std::size_t A>
void foo(myClass<T, A> arg1, typename std::common_type<T>::type arg2);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note that std::common_type<T>::type is essentially just T, but because the type of arg2 is now a dependent type (its name appears to the right of a ::), it is not deduced. Therefore, only the first argument takes part in deduction and produces T = double unambiguously, and then the second function parameter just has type double, and the usual conversions take place.
As a rule of thumb, template argument deduction does not cross ::.
You are running into problems with template type deduction.
Both arguments are given "equal standing" when deducing the value of T, and in this case the two arguments disagree -- one says T should be int, the other says T should be double.
The right way to fix this is with Koenig operators.
Make += and + and the like friends of your class and implement inline:
template<class T, size_t a>
class myClass {
// etc
public:
friend myClass operator+(myClass lhs, const T& rhs) {
lhs += rhs;
return std::move(lhs);
}
friend myClass& operator+=(myClass& lhs, const T& rhs) {
// do addition, depends on `a`
return *this;
}
};
this technique does something strange. It creates non-template operators based on the template type of the class. These are then found via ADL (Koenig lookup) when you invoke + or +=.
You get one of these operators per template instantiation, but they aren't template operators, so const T& isn't deduced, and conversion happens as expected.