Функция Friend шаблонной структуры с типами аргументов, зависящими от внутренних структур

0

Я хотел бы определить шаблонную структуру с помощью функции friend, типы аргументов которой выведены из типов, определенных внутри структуры. Функция friend должна быть вызвана без явной спецификации типа, если соответствующая структура была создана.

Кажется, что работает следующий подход:

template <typename T> struct A {
    typedef T const& underlying_param_type;
    typedef A<T>& param_type;
    friend void mutateA(param_type a, underlying_param_type b) { a.data_ = b; }
    T data_;
};

Если определить функцию друга с типами параметров, которые не зависят от внутренних элементов структуры, можно разделить интерфейс и реализацию следующим образом:

template <typename T> struct B;
template <typename T> void mutateB(B<T>& a, T const& b);

template <typename T> struct B {
    friend void mutateB <> (B<T>& a, T const& b);
    T data_;
};

template <typename T> void mutateB(B<T>& a, T const& b) { a.data_ = b; }

Теперь мне интересно, можно ли комбинировать оба подхода. Следующий подход не работает (clang++ 3.3, g++ 4.8.2, -std = С++ 11):

template <typename T> struct C;
template <typename T> void mutateC(typename C<T>::param_type a, typename C<T>::underlying_param_type b);

template <typename T> struct C {
    typedef T const& underlying_param_type;
    typedef C<T>& param_type;
    friend void mutateC <> (typename C<T>::param_type a, typename C<T>::underlying_param_type b);
    T data_;
};

template <typename T> void mutateC(typename C<T>::param_type a, typename C<T>::underlying_param_type b) { a.data_ = b; }

int main() {
    A<int> a;
    mutateA(a, 1);

    B<int> b;
    mutateB(b, 1);

    C<int> c; // error: no function template matches function template specialization 'mutateC'
    mutateC(c, 1);

    return 0;
}

Я предполагаю, что последний подход завершился неудачно, поскольку вывод аргумента шаблона не работает через ::. Есть идеи?

  • 0
    <> в <T> ? Может быть и больше, но ваша проблема выглядит как синтаксические ошибки в объявлении вашего друга. Начать с более простого объявления друга и заставить его работать? (где вы друг конкретной специализации)
  • 0
    После изменения <> в <T> оператор C <int> c; компилируется, но mutateC (c, 1) - нет. mutateC <int> (c, 1) работает в этом параметре, но этого недостаточно для моего варианта использования.
Показать ещё 3 комментария
Теги:
struct
templates
friend-function

2 ответа

0
Лучший ответ

Добавление уровня косвенности решает проблему:

template <typename T> struct C;
template <typename T> void mutateC_impl(typename C<T>::param_type a, typename C<T>::underlying_param_type b);

template <typename T> struct C {
    typedef T const& underlying_param_type;
    typedef C<T>& param_type;
    friend void mutateC(typename C<T>::param_type a, typename C<T>::underlying_param_type b) { mutateC_impl<T>(a, b); }
    friend void mutateC_impl<T>(typename C<T>::param_type a, typename C<T>::underlying_param_type b);
    private: T data_;
};

template <typename T> void mutateC_impl(typename C<T>::param_type a, typename C<T>::underlying_param_type b) { a.data_ = b; }
1

Сделайте две небольшие изменения:

  • Друг void mutateC...
  • mutateC <int> (c, 1);
  • 0
    Спасибо. «Функция Friend должна вызываться без явного указания типа, если была создана соответствующая структура».

Ещё вопросы

Сообщество Overcoder
Наверх
Меню