Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Template friend function not compiling (full working code example)

25 views
Skip to first unread message

JiiPee

unread,
Jan 22, 2015, 3:21:04 PM1/22/15
to
Sorry for last time not providing full code. Now I paste here the full
code so you can test the error yourself. I have GCC 4.8, debug build,
C++11 on, Windows XP. Error message: "error: declaration of 'operator*'
as non-function".

So I tried to add a simple multiplication function as a friend. And it
to be template function. But it conflicts with the other multiplication
function.

It works if I commend out the other * operator (see the code).
Any idea how to fix this? thanks

Full console based code which does not compile:

#include <iostream>

using namespace std;

template <typename T> class Vector2D2;
template <typename T> Vector2D2<T> operator * (const T& pointXY, const
Vector2D2<T>& point);

template <typename T>
class Vector2D2
{
public:
// if I commend this out the code compiles with no problems
Vector2D2 operator * (const Vector2D2& point) const { return *this; }

friend Vector2D2<T> operator* <> (const T& pointXY, const
Vector2D2<T>& point);

int y;
private:
T b;
};

template <typename T>
Vector2D2<T> operator* (const T& pointXY, const Vector2D2<T>& point)
{
Vector2D2<T> cc;
cc.b = point.b * pointXY;
return cc;
}


int main()
{
Vector2D2<double> jj, mm;
mm = 3.0 * jj;
std::cout<<mm.y;
return 0;
}

Paavo Helde

unread,
Jan 22, 2015, 4:07:32 PM1/22/15
to
JiiPee <n...@notvalid.com> wrote in news:DYcww.293940$Ud7.2...@fx11.am4:
As I said before, you need to tell the computer the friend operator* is
not from the closest scope (class Vector2D2), but from another scope.
Unfortunately, just adding "::" for global scope does not work as this
gets merged to the preceding token (Vector2D2<T>). One solution might be
to put the operator* in a namespace (all custom C++ code ought to be in a
namespace anyway, so this should not a problem). The following at least
compiles with g++ (but crashes the MSVC++ compiler ;-): Probably there
are other cleaner solutions...

#include <iostream>

using namespace std;
namespace abc {


template <typename T> class Vector2D2;
template <typename T> Vector2D2<T> operator * (const T& pointXY, const
Vector2D2<T>& point);

template <typename T>
class Vector2D2
{
public:
// if I commend this out the code compiles with no problems
Vector2D2 operator * (const Vector2D2& point) const { return *this; }

friend Vector2D2<T> abc::operator*<>(const T& pointXY, const
Vector2D2<T>& point);

int y;
private:
T b;
};

template <typename T>
Vector2D2<T> operator* (const T& pointXY, const Vector2D2<T>& point)
{
Vector2D2<T> cc;
cc.b = point.b * pointXY;
return cc;
}
} // namespace abc

using namespace abc;

JiiPee

unread,
Jan 22, 2015, 4:35:54 PM1/22/15
to
On 22/01/2015 21:07, Paavo Helde wrote:
> As I said before, you need to tell the computer the friend operator* is
> not from the closest scope (class Vector2D2), but from another scope.
> Unfortunately, just adding "::" for global scope does not work as this
> gets merged to the preceding token (Vector2D2<T>). One solution might be
> to put the operator* in a namespace (all custom C++ code ought to be in a
> namespace anyway, so this should not a problem). The following at least
> compiles with g++ (but crashes the MSVC++ compiler ;-): Probably there
> are other cleaner solutions...
>
>
> friend Vector2D2<T> abc::operator*<>(const T& pointXY, const
> Vector2D2<T>& point);
>
>

Yesss! Wow. Thanks a lot !! you saved hours of my time. Now I can
continue with the project :).
I have all these classes in ct-namespace, so I just added ct:: and it
worked straight away.

Need to study this also properly... kind of new to me.
0 new messages