Templated friends

P

Pete C.

I'm trying to make a templated function a friend like this:

class cls
{
...
friend cls func<> (const cls& a, const cls& b);
};

template< template<class> class Op>
cls func (const cls& a, const cls& b)
{
...
}

That seems to be what TC++PL SE shows in C.13.2, but the compiler seems to
be interpreting it as a data declaration:
error C2143: syntax error : missing ';' before '<'
error C2460: 'func' : uses 'cls', which is being defined: see declaration of
'cls'
error C2433: 'func' : 'friend' not permitted on data declarations
error C2238: unexpected token(s) preceding ';'
The compiler docs on those diagnostics don't seem to have anything to do
with friend.

What am I doing wrong?

Thanks!
- Pete
 
V

Victor Bazarov

Pete C. said:
I'm trying to make a templated function a friend like this:

class cls
{
...
friend cls func<> (const cls& a, const cls& b);
};

template< template<class> class Op>
cls func (const cls& a, const cls& b)
{

The definition of this function has no 'Op' used. There is no
way for a compiler to figure out the template argument from the
function arguments. That's why you have to always explicitly
specify it.
...
}

That seems to be what TC++PL SE shows in C.13.2,

I don't have my copy of the SE here (it's at work), are you sure
the example is precisely as you show here?
but the compiler seems to
be interpreting it as a data declaration:
error C2143: syntax error : missing ';' before '<'
error C2460: 'func' : uses 'cls', which is being defined: see declaration of
'cls'
error C2433: 'func' : 'friend' not permitted on data declarations
error C2238: unexpected token(s) preceding ';'
The compiler docs on those diagnostics don't seem to have anything to do
with friend.

What am I doing wrong?

Perhaps you're not following the rules of syntax. Why do you
think what you wrote should work? Where did you see the syntax
you're using?

'func' is a function _template_. If you want a _template_ to be
a friend (which actually means that _all_possible_instantiations_
of that template are friends), you need to begin your declaration
with the keyword "template". If you want one _particular_
instance of that template to be a friend, you need to give the
template _argument_ (put something in the <>).

Of course it's entirely possible that you're not using the right
compiler for the code. Older VC++ can't handle template friends
very well.

Victor
 
I

Ian

Pete said:
I'm trying to make a templated function a friend like this:

class cls
{
...
friend cls func<> (const cls& a, const cls& b);
};

template< template<class> class Op>
cls func (const cls& a, const cls& b)
{
...
}

That seems to be what TC++PL SE shows in C.13.2, but the compiler seems to
be interpreting it as a data declaration:
error C2143: syntax error : missing ';' before '<'
error C2460: 'func' : uses 'cls', which is being defined: see declaration of
'cls'
error C2433: 'func' : 'friend' not permitted on data declarations
error C2238: unexpected token(s) preceding ';'
The compiler docs on those diagnostics don't seem to have anything to do
with friend.

What am I doing wrong?
Each instance of a template is unique. So (unfortunately) you have to
be explicit;

class cls;

template< class Op>
cls func(const cls& a, const cls& b)
{
....
}

class cls
{
friend cls func<int> (const cls& a, const cls& b);
};

Ian
 
P

Pete C.

Victor said:
The definition of this function has no 'Op' used. There is no
way for a compiler to figure out the template argument from the
function arguments. That's why you have to always explicitly
specify it.


I don't have my copy of the SE here (it's at work), are you sure
the example is precisely as you show here?

template<class T> class Matrix;

template<class T> class Vector {
T v[4];
public:
friend Vector operator*<>(const Matrix<T>&, const Vector&);
// ...
};

template<class T> class Matrix {
Vector<T> v[4];
public:
friend Vector<T> operator*<>(const Matrix&, const Vector<T>&);
// ...
};

template<class T> Vector<T> operator*(const Matrix<T>& m, const Vector<T>&
v)
{
// ...
}
Perhaps you're not following the rules of syntax. Why do you
think what you wrote should work? Where did you see the syntax
you're using?

'func' is a function _template_. If you want a _template_ to be
a friend (which actually means that _all_possible_instantiations_
of that template are friends), you need to begin your declaration
with the keyword "template". If you want one _particular_
instance of that template to be a friend, you need to give the
template _argument_ (put something in the <>).

I changed it to:
template< template<class> class Op> friend variant binaryoperator (const
variant& a, const variant& b);
and it worked!

I had tried it with 'friend' before 'template<...>', but that failed. Then I
looked at TC++PL and its complete lack of 'template<...>' made me think that
it was unneccessary.

Thanks again!
Of course it's entirely possible that you're not using the right
compiler for the code. Older VC++ can't handle template friends
very well.

It's VC++ 7.1, so I can pretty much blame any errors on myself ;)

- Pete
 
G

Gianni Mariani

Ian said:
Each instance of a template is unique. So (unfortunately) you have to
be explicit;

You can make a template friend. friends are specified as declarations,
so if you can declare it, you can make a friend out of it (in theory).

class cls;

template< class Op>
cls func(const cls& a, const cls& b);

class cls
{
template< class Op>
friend cls func(const cls& a, const cls& b);
};


.... now, that's not a very interesting template, maybe the OP wanted
somthing like this:

class cls;

template<class TA, class TB>
cls func(const TA& a, const TB& b);

class cls
{
template<class TA, class TB>
friend cls func(const TA& a, const TB& b);
};
 
P

Pete C.

Gianni Mariani wrote:
You can make a template friend. friends are specified as
declarations, so if you can declare it, you can make a friend out of
it (in theory).

class cls;

template< class Op>
cls func(const cls& a, const cls& b);

class cls
{
template< class Op>
friend cls func(const cls& a, const cls& b);
};

I had tried:
friend template<...> cls func ... ;

Then TC++PL confused me with the syntax as shown in the topic post, but with
a nudge from Victor Bazarov I came the correct syntax. :)
... now, that's not a very interesting template, maybe the OP wanted
somthing like this:

class cls;

template<class TA, class TB>
cls func(const TA& a, const TB& b);

class cls
{
template<class TA, class TB>
friend cls func(const TA& a, const TB& b);
};

I actually had: template<template<class> class Op>
To pass a template sort of like this:
cls = func<std::plus>(cls(123), cls(321))

- Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,816
Latest member
SapanaCarpetStudio

Latest Threads

Top