Это чрезвычайно безумная реализация арифметики с фиксированной точкой в C++. Пожалуйста, никаких комментариев о том, насколько плохи и бессмысленны все это.Сложная перегрузка и шаблоны операторов
Как вы можете видеть, есть базовый тип T
и число двоичных разрядов для дробной части N
. Необходимо, чтобы FixedNum<int, A> + FixedNum<int, B>
оценивался как FixedNum<int, MAX(A, B)>.
Вот как я пытаюсь его реализовать. Однако GCC говорит, что присвоения x
в последних строках неверны, поскольку x
защищен. Что не так?
#define MAX(a,b) (((a)>(b))?(a):(b))
template <typename T, int N>
class FixedNum
{
public:
template <int N2>
friend FixedNum& operator+(const FixedNum& f, const FixedNum& g);
template <int N2>
friend FixedNum& operator+=(const FixedNum& f, const FixedNum& g);
FixedNum(T x): x (x) {}
T num() const { return x; }
int point() const { return N; }
protected:
T x;
};
template <typename T, int N, int N2>
FixedNum<T, MAX(N, N2)>& operator+(const FixedNum<T, N>& f, const FixedNum<T, N2>& g)
{
return FixedNum<T, N>(f) += g;
}
template <typename T, int N, int N2>
FixedNum<T, MAX(N, N2)>& operator+=(const FixedNum<T, N>& f, const FixedNum<T, N2>& g)
{
#if N2 <= N
f.x += g.x << (N-N2);
#else
f.x <<= (N2-N);
f.x += g.x;
#endif
}
Это правда, что 'x' защищен, и, очевидно, вы пытаетесь объявить оператор + = а друг. Но я думаю, что ваша декларация вашего друга не соответствует вашему оператору. – blackbird
Я не верю, что разные специализации шаблона имеют доступ к переменным 'protected' друг друга, если специализации не являются друзьями. См. Http://stackoverflow.com/questions/11001480/templated-conversion-constructor-fails-to-access-protected-data-members – SubSevn