Ошибка здесь в том, какой тип decltype
выводит из вашего выражения; к сожалению, сообщения об ошибках не совсем ясны, и это действительно немного сложная проблема.
Рассмотрим тип выражения 0 + 0
. Это int
, да, но что более важно это значение (неофициально, это временно). Это означает, что decltype(0 + 0)
- это не int
, а int&&
. Теперь учтите, что ваш код ничем не отличается в этом отношении: у вас все еще есть значение.
Проблема в том, что нетиповые параметры шаблона не могут быть ссылками на значения, поэтому у вас не может быть Int<int&&>
из-за типа второго параметра. Что вы можете сделать, хотя это:
#include <type_traits>
// ...
template <class IntType, class IntType_1>
auto operator+(const Int<IntType>& lhs, // be const-correct!
const Int<IntType_1>& rhs)
-> Int<typename std::remove_reference<
decltype(lhs.getValue() + rhs.getValue())>::type>
{
return lhs.getValue() + rhs.getValue();
}
Это снимает ссылку с int&&
, давая вам голый тип int
. Надеемся, что сообщение об ошибке в gcc имеет немного больше смысла: оно пытается сказать вам, что вы не можете использовать int&&
для параметра не-типа.
Другая проблема, хотя, вероятно, и не является проблемой, заключается в том, что целочисленная арифметика претерпевает то, что называется обычными арифметическими преобразованиями . Таким образом, результат добавления значений двух Int<char>
на самом деле будет int
, поэтому ваш тип возврата должен быть Int<int>
(и с фиксированным кодом).
Проблема в том, что вы не определили static_numeric_limits<int>
. Но, как я уже сказал, я подозреваю, что это не проблема, и вы на самом деле определили это, просто не отображается в вашем вопросе.