我想用友元函数定义模板化结构,其参数类型是从结构中定义的类型派生的。如果相应的结构已经实例化,那么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_;
};
如果使用不依赖于结构内部的参数类型定义friend函数,则可以按如下方式分离接口和实现:
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 = c ++ 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 :(得分:1)
做两处小改动:
答案 1 :(得分: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; }