【发布时间】:2013-12-22 13:49:43
【问题描述】:
我想定义一个带有友元函数的模板结构,其参数类型派生自结构中定义的类型。如果对应的结构已经被实例化,友元函数应该可以在没有明确类型说明的情况下调用。
以下方法似乎有效:
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;
}
我猜最后一种方法失败了,因为模板参数推导不适用于 ::。有什么想法吗?
【问题讨论】:
-
<>变成<T>?也许更多,但您的问题看起来像您的朋友声明中的语法错误。从一个更简单的朋友声明开始并让它发挥作用? (您与特定专业的朋友) -
将改为
后声明C c;编译但 mutateC(c, 1) 不编译。 mutateC (c, 1) 在此设置中有效,但这对于我的用例来说还不够。 -
啊,是的。对于任意
typedef,您要求的内容需要反转图灵完整计算,因此是不可行的。提供更多细节,因为特殊情况可能是可行的。您的第一个有效的原因是 ADL 找到了A<T>参数的朋友,例如。在非 workimg 示例中传递的类型对 ADL 没有帮助,为此,您需要在所有类型上反转template替换。您编写的手动反转可以使用辅助函数来完成。 -
最后一种方法失败是正确的,因为参数是不可推导的。你为什么要这样做?
friend void mutateA(A& a, const T& b) { a.data_ = b; }或者更好的friend void mutateA(A& a, T b) { a.data_ = std::move(b); }有什么问题? -
在我的实际用例中,我有很多类似结构的友元函数。特别是,只有少数参数类型是从 T 派生的。派生规则将来可能会改变。引入 typedef 是为了使此类更改变得容易。我在工作解决方案(结构 A)中看到的唯一缺点是接口和实现没有分开。我想知道是否有办法将它们分开。如果这样的解决方案只是用一种丑陋换另一种,我可能会继续使用我所拥有的。无论如何,看看其他解决方案会很有趣。
标签: c++ templates struct friend-function