【发布时间】:2011-07-15 06:44:38
【问题描述】:
我有一个课程模板Foo<T>。
我想实现一个非成员函数Bar,它接受两个Foos 并返回一个Foo。我希望Bar 成为非会员,因为调用者写Bar(f1, f2) 比f1.Bar(f2) 更自然。我还希望Bar 成为inline,因为计算简单且频繁。
template <typename T>
inline Foo<T> Bar(const Foo<T> &lhs, const Foo<T> &rhs) {
...
}
诀窍是Bar 需要访问Foo 的私人数据。我不希望有私有数据的访问者——没有充分的理由向用户公开私有数据。所以我想让Bar成为Foo的朋友。
template <typename T>
class Foo {
...
private:
T w, x, y, z;
friend Foo<T> Bar(const Foo<T> &lhs, const Foo<T> &rhs);
};
这就是我遇到麻烦的地方。编译器抱怨:
当友元声明引用函数模板的特化时,不能使用内联说明符。
此规则是由标准强加的还是特定于 MSVC++?
这是我尝试过的:
将
Bar设为 const 公共成员函数,然后声明一个仅返回lhs.Bar(rhs)的非成员版本。这似乎是最简单的解决方案。删除
inline提示,知道编译器将决定内联而不管提示。那么这是否违反了单一定义规则?它仍然必须在头文件中定义,因为它是一个函数模板。-
使用虚拟模板类型声明成员函数:
template <typename T> class Foo { ... private: T w, x, y, z; // Note that this declaration doesn't actually use Dummy. It's just there to // satisfy the compiler. template <typename Dummy> friend Foo<T> Bar(const Foo<T> &lhs, const Foo<T> &rhs); };
我不完全确定为什么会这样,但它确实满足了编译器。
有没有更好的解决方案?
【问题讨论】:
标签: c++ friend function-templates non-member-functions