CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Oct 2009
    Posts
    13

    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.

  2. #2
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    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

  3. #3
    Join Date
    Apr 2009
    Location
    Netherlands
    Posts
    91

    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.

  4. #4
    Join Date
    Oct 2009
    Posts
    13

    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?

  5. #5
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Proper syntax for template friend operator in a template class?

    Quote Originally Posted by tbabb View Post
    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

  6. #6
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Proper syntax for template friend operator in a template class?

    Quote Originally Posted by JohnW@Wessex View Post
    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

  7. #7
    Join Date
    Oct 2009
    Posts
    13

    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.

  8. #8
    Join Date
    Oct 2008
    Posts
    1,456

    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;
    }

  9. #9
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Proper syntax for template friend operator in a template class?

    Quote Originally Posted by tbabb View Post
    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

  10. #10
    Join Date
    Oct 2009
    Posts
    13

    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;
    }

  11. #11
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Proper syntax for template friend operator in a template class?

    Quote Originally Posted by tbabb View Post
    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
  •  





Click Here to Expand Forum to Full Width

Featured