Re: function template specialization
On Mar 10, 1:13 am, aaragon <alejandro.ara...@gmail.com> wrote:
Hi... after trying several things with some templated code I
decided to ask the experts a couple of things. I have the
following class template:
template<class A>
class Expr {
A a_;
public:
... // some public functions
...
friend inline std::ostream& operator<<(std::ostream& os, const
Expr<A>& e) {
os<<e.a_();
return os;
}
};
operator<< works just fine,
But maybe not for the reason you think:-).
but then I wanted to have the operator<< with different
behaviors depending on the template parameter. So, I tried the
following inside the class:
// declaration inside the class
friend std::ostream& operator<<<A>(std::ostream& os, const Expr&
e);
and defining the function outside:
template <class A>
inline std::ostream& operator<<(std::ostream& os, const Expr<A>&
e) {
os<<e();
return os;
}
In sum, you declare a non-template function as friend, and you
implement a function template. They're not the same thing.
They way I usually handle this is more or less what Ian
suggested: I define a member function which does the actual
work, and then invoke it in my operator<<. But it's possible to
declare function templates, or specializations of function
templates, as friends. Note however that to do so, it is
necessary to declare the function template before the class
template definition.
Then I got just too many errors because of ambiguous calls and
others like:
cppblas.hpp:862: error: template-id 'operator<< <UnOp<Vector<double>,
TrOp> >' for 'std::basic_ostream<char, std::char_traits<char> >&
operator<<(std::basic_ostream<char, std::char_traits<char> >&, const
Expr<UnOp<Vector<double>, TrOp> >&)' does not match any template
declaration
So then, I decided to forward the function call to another
function, say print:
template <class A>
inline std::ostream& print(std::ostream& os, const Expr<A>& e) {
os<<e();
return os;
}
so this also works fine, and now I can specialize the function
for specific class of A:
template <>
inline std::ostream& print<someClass>(std::ostream& os, const
Expr<someClass>& e) {
// partially specialized for someClass
return os;
}
Now the questions is, is this the better way to do this?
That's the way I do it.
Forwarding a function call seems right, but probably it can be
done without another function. I tried hard overloading
operator<< but no success. Any hints??
I'm not sure of the exact syntax, because I don't use it, but
you'd probably have to start with something like:
template < typename T >
class Expr ;
template< typename T >
std::ostream& operator<<( std::ostream&, Expr< T > const& ) ;
template< typename T >
class Expr
{
// ...
friend template<> std::ostream& operator<<(
std::ostream&, Expr< T > const7 ) ;
// (or something like that. As I said, I'm not too
// sure of the syntax.)
} ;
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34