-
April 12th, 2010, 02:25 AM
#1
Proper syntax for template friend operator in a template class?
Hi,
What is the proper way to have an operator that has its own template parameters, which is also a friend of a template class?
What I mean is something like this:
Code:
template <typename T> class Foo;
template<typename A, typename B> Foo<B> operator*(Foo<A> a, Foo<B> b);
template <typename T>
class Foo{
T thing;
//'structors and such ...
template <typename B> friend Foo<B> operator* <> (Foo<T> a, Foo<B> b);
}
//Foo.cpp:
template<typename A, typename B> Foo<B> operator*(Foo<A> a, foo<B> b){
...
}
This code does not compile (even when fleshed out with constructors, fn bodies, etc.), as the compiler complains about "invalid use of template-id 'operator*<>'". When I remove it, the compiler fails to find a match for the * operator. Finally, using two separate template<...> declarations (i.e. one before the other) also produces a compiler error. Am I forgetting something obvious?
P.S.: I have been using this FAQ and also this one as guides for messing with templates-- they are extensive and have proven super useful, but they don't really touch on this particular problem.
P.P.S. As an aside, when I use a more complicated form of this construct, I get an internal compiler error with GCC on OSX. Right now I'm trying to whittle the problem down to the most basic form.
-
April 12th, 2010, 05:56 AM
#2
Re: Proper syntax for template friend operator in a template class?
I usually define template friend operators within the template class definition.
"It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
Richard P. Feynman
-
April 12th, 2010, 07:57 AM
#3
Re: Proper syntax for template friend operator in a template class?
I remember posting something about GCC having trouble with friends and templates. Perhaps you can find something useful in this old thread of mine?
http://www.codeguru.com/forum/showthread.php?t=480940
It's been a while since I've used template or friend syntax so I'm not sure if that post might be related to your problem.
-
April 12th, 2010, 10:06 PM
#4
Re: Proper syntax for template friend operator in a template class?
I still get "no match for operator *" when I try to declare operator* inside the template.
Any other ideas? Has anyone been able to do this themselves?
-
April 13th, 2010, 03:14 AM
#5
Re: Proper syntax for template friend operator in a template class?
Originally Posted by tbabb
Has anyone been able to do this themselves?
Can't help with GCC, but this all compiles fine under VC2008
Code:
template <typename T> class Foo;
template<typename A, typename B> Foo<B> operator*(Foo<A> a, Foo<B> b);
template <typename T>
class Foo
{
T thing;
//'structors and such ...
template <typename B> friend Foo<B> operator* <> (Foo<T> a, Foo<B> b);
};
//Foo.cpp:
template<typename A, typename B> Foo<B> operator*(Foo<A> a, Foo<B> b)
{
return Foo<B>();
}
int main()
{
Foo<int> foo1;
Foo<double> foo2;
foo2 = foo1 * foo2;
}
"It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
Richard P. Feynman
-
April 13th, 2010, 09:19 AM
#6
Re: Proper syntax for template friend operator in a template class?
Originally Posted by JohnW@Wessex
Can't help with GCC, but this all compiles fine under VC2008
This doesn't define the friend relation that's desired. If you change the code to
Code:
template<typename A, typename B> Foo<B> operator*(Foo<A> a, Foo<B> b)
{
a.thing = 0;
return Foo<B>();
}
you get a compiler error for trying to access a private member.
However, if you change the friend declaration to
Code:
template <typename A, typename B> friend Foo<B> operator* <> (Foo<A> a, Foo<B> b);
it does work.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
April 14th, 2010, 12:25 AM
#7
Re: Proper syntax for template friend operator in a template class?
No dice for me. I either get:
error: declaration of 'class T'
error: shadows template parm 'class T'
or
error: invalid use of template-id 'operator*<>' in declaration of primary template
if I use different type parameter names, which I suspect wouldn't give me what I want anyway, since it doesn't seem to connect the friend function's argument's params to the containing template.
-
April 14th, 2010, 02:00 AM
#8
Re: Proper syntax for template friend operator in a template class?
the code in JohnW@Wessex post doesn't compile on Comeau...
so I suppose that the syntax "template <typename B> friend Foo<B> operator* <> (Foo<T> a, Foo<B> b);" is not standard and that your only alternative is to define your function in the class body ( by the way, in your code sample you seem putting the operator* definition in a cpp file, which is not correct unless explicitly instantiated there ) either directly or via a local 'include "Foo.operator.star.inl";' or better (IMHO) with an inline forwarder:
Code:
template <typename T>
class Foo
{
T thing;
template <typename B> friend Foo<B> operator* (Foo<T> a, Foo<B> b)
{
return a.right_multiply( b );
}
template <typename B> inline Foo<B> right_multiply(Foo<B> b) const;
};
template <typename T>
template <typename B> Foo<B> Foo<T>::right_multiply(Foo<B> b) const
{
return /*whatever*/ b;
}
-
April 14th, 2010, 07:15 AM
#9
Re: Proper syntax for template friend operator in a template class?
Originally Posted by tbabb
error: declaration of 'class T'
error: shadows template parm 'class T'
or
error: invalid use of template-id 'operator*<>' in declaration of primary template
Please post the code and indicate the line that produces this error.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
May 23rd, 2010, 09:55 PM
#10
Re: Proper syntax for template friend operator in a template class?
OK, I am digging this back up, since I've had some time to get back to my project.
I see now that there's a subtle difference between what I've posted and what I've been testing. My code does not use the template parameter in the arguments:
Code:
namespace test{
template<class T> class MinimalTest;
template <class T>
class MinimalTest {
public:
T thing;
MinimalTest(T thing);
virtual ~MinimalTest();
template <class U> friend MinimalTest<U> operator* (MinimalTest<T> a, MinimalTest<T> b){
return MinimalTest<U>(a.thing*b.thing);
}
};
}
//MinimalTest.cpp:
#include <iostream>
#include <cstdio>
#include "MinimalTest.h"
using namespace test;
template<class T> MinimalTest<T>::MinimalTest(T thing):thing(thing) {
// do nothing
}
template<class T> MinimalTest<T>::~MinimalTest() {
// do nothing
}
int main(int argc, char **argv){
MinimalTest<int> a(500);
MinimalTest<int> b(400);
MinimalTest<double> d = a*b; // <-- ERROR HERE. "no match for operator *"
std::cout << d.thing;
return 0;
}
-
May 24th, 2010, 05:53 AM
#11
Re: Proper syntax for template friend operator in a template class?
Originally Posted by tbabb
Code:
template <class T>
class MinimalTest {
public:
template <class U> friend MinimalTest<U> operator* (MinimalTest<T> a, MinimalTest<T> b){
return MinimalTest<U>(a.thing*b.thing);
}
};
This function doesn't make any sense. In order to call it you will have to specify the template argument, since it cannot be deduced. But since this is an operator you will get a very weird syntax. Something like
Code:
operator *<double>(a, b);
Second this is a member function of MinimalTest. I think you want it to be a global function.
Please describe what you want to achieve, because it is not clear at all from your code. In particular, why should the result of a*b be a MinimalTest<double> and not a MinimalTest<int>?
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|