I have a function template foo
that has to perform different computations depending on whether the template parameter is a real or a complex number. In any case, the result will be a real number, e.g. double
, even if the template parameter is std::complex<double>
. Therefore, my function looks as follows:
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);
Now foo
must be a friend function of the class C
, so I made the following declaration:
template <class S>
class C
{
friend typename RealType<S>::type foo(C<S> &c);
// ...
};
However, when I instantiate C<std::complex<double> >
the compiler says that foo
cannot access the private members of c
. It works fine for C<double>
. Is there any solution to this (that works with C++98)? I understand that foo
cannot be a member of C
, as this will prevent the partial specialization.
BTW: Is this really a specialization? The signatures of both versions of foo
look the same, but in fact they are somewhat different when the real types are plugged in.
Make sure that class C
declares foo
a friend after foo
has been declared.
You may need to use forward declarations for that:
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
};