C++ 中的特殊友元函数
Specialized friend function in C++
我有一个函数模板 foo
必须根据模板参数是实数还是复数执行不同的计算。在任何情况下,结果都将是一个实数,例如double
,即使模板参数是std::complex<double>
。因此,我的函数如下所示:
template <class S>
struct RealType
{
typedef S type;
};
template <class S>
struct RealType<std::complex<S> >
{
typedef S type;
};
template <class S>
class C;
template <class S>
typename RealType<S>::type foo(C<S> &c);
template <class S>
typename RealType<std::complex<S> >::type foo(C<std::complex<S> > &c);
现在foo
一定是classC
的友元函数,所以我做了如下声明:
template <class S>
class C
{
friend typename RealType<S>::type foo(C<S> &c);
// ...
};
但是,当我实例化 C<std::complex<double> >
时,编译器说 foo
无法访问 c
的私有成员。它适用于 C<double>
。对此有任何解决方案吗(适用于 C++98)?我知道 foo
不能成为 C
的成员,因为这会阻止部分专业化。
顺便说一句:这真的是专业吗? foo
两个版本的签名看起来是一样的,但实际上在插入真实类型时它们有些不同。
确保 class C
声明 foo
朋友 在 foo
声明之后。
您可能需要为此使用前向声明:
template <class S> class C;
// foo declarations here
template <class S> class C
{
template<class X> friend typename RealType<X>::type foo(C<X> &c); // friend the template
friend typename RealType<S>::type foo<>(C &c); // friend the specialization
};
我有一个函数模板 foo
必须根据模板参数是实数还是复数执行不同的计算。在任何情况下,结果都将是一个实数,例如double
,即使模板参数是std::complex<double>
。因此,我的函数如下所示:
template <class S>
struct RealType
{
typedef S type;
};
template <class S>
struct RealType<std::complex<S> >
{
typedef S type;
};
template <class S>
class C;
template <class S>
typename RealType<S>::type foo(C<S> &c);
template <class S>
typename RealType<std::complex<S> >::type foo(C<std::complex<S> > &c);
现在foo
一定是classC
的友元函数,所以我做了如下声明:
template <class S>
class C
{
friend typename RealType<S>::type foo(C<S> &c);
// ...
};
但是,当我实例化 C<std::complex<double> >
时,编译器说 foo
无法访问 c
的私有成员。它适用于 C<double>
。对此有任何解决方案吗(适用于 C++98)?我知道 foo
不能成为 C
的成员,因为这会阻止部分专业化。
顺便说一句:这真的是专业吗? foo
两个版本的签名看起来是一样的,但实际上在插入真实类型时它们有些不同。
确保 class C
声明 foo
朋友 在 foo
声明之后。
您可能需要为此使用前向声明:
template <class S> class C;
// foo declarations here
template <class S> class C
{
template<class X> friend typename RealType<X>::type foo(C<X> &c); // friend the template
friend typename RealType<S>::type foo<>(C &c); // friend the specialization
};