ReAl (07.01.2012 14:06, просмотров: 158) ответил Скрипач на Спасибо. А почему тогда не проходит во это:
Ну тот шаблонизированный оператор — не friend, его в класс вписывать не нужно. А тут... Сначала оно обижается на то, что T VAL(strict a); выходит как-бы нешаблонным (просьба не спрашивать почему — я пока только потихоньку про все это читаю). Нужно к объявлению другом тоже угловые скобочки прикрутить. Но для этого нужно forward declaration функции перед классом сделать. Но у функции аргумент — объект класса, нужно forward declaration класса перед функцией сделать. Итого как-то так:
template <typename T, data_id_t t, int subtype> class strict;
template <typename T, data_id_t t, int subtype> T VAL(strict<T, t, subtype> a);
template <typename T, data_id_t t, int subtype> class strict{
T val;
public:
explicit strict(T init_val=0) : val(init_val) { }
strict operator+(const strict b){ return strict(val + b.val);}
strict operator-(const strict b){ return strict(val - b.val);}
strict operator/(const T b){ return strict(val / b);}
T operator/(const strict b){ return val / RAW_VALUE(b);}
friend strict operator*(const strict a, const T b){ return strict(a.val * b);}
friend strict operator*(const T b, const strict a){ return strict(a.val * b);}
friend T VAL<>(strict a);
};
template <typename T, data_id_t t, int subtype>
T VAL(strict<T, t, subtype> a){ return a.val; }
Говорю же, гранаты у них не той конструкции ну их в баню, обилие друзей. Пока каждому расскажешь про класс, да классу про каждого... Хорошо, когда друзья простые и прямо в классе вписались. А если посложнее будут? Вот я и предложил часть операторов сделать членами класса с одним операндом (ну нет тут нужды их из класса выделять во внешние friend-ы), а обеспечивающие комутативность сделать внешними не-friend подстановками, для обеспечения комутативности через уже имеющийся «односторонний» опреатор не нужно доступа к внутренностям и читается легко.
Но даже если всё как было — все равно я за то, чтобы комутативность показать явно
...
friend strict operator*(const strict& left, const T& right){ return strict(left.val * right);}
// хотя тут уже ну совсем не нужно быть другом... никакого доступа к внутренностям
friend strict operator*(const T& left, const strict& right){ return right * left;}
...