我想定义一个带有友元函数的模板结构,其参数类型派生自结构中定义的类型。如果相应的结构已经被实例化,友元函数应该可以在没有明确类型说明的情况下被调用。
以下方法似乎有效:
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=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;
}
我猜最后一种方法失败了,因为模板参数推导不适用于::。有任何想法吗?