www.digitalmars.com         C & C++   DMDScript  

c++ - template friends

reply "Steve Strand" <snstrand attbi.com> writes:
Can the compiler handle template friends? The code below results in a
linker error since the compiler calls the template friend function
getitem() but never generates code for it. Compiling with the -XD flag
makes the compiler say that vector<int>::data is not accessible (as if
the friend declaration did not exist). The compiler version notes say
that 8.29 implements template friends (I am using version 8.32) so I
wonder if I am doing something wrong.

Steve Strand

template<class T>
class vector {
    T data[4];
public:
    vector(T k) {for (int j=0; j<4; ++j) data[j]= k;}
    friend T getitem(const vector<T>& vref, int j);
};

template<class T>
T getitem(const vector<T>& vref, int j)
{return vref.data[j];}

int main()
{
vector<int> vint(1);
int j= getitem(vint,1);
}
Feb 25 2003
next sibling parent Richard Grant <fractal clark.net> writes:
In article <b3gura$1jdg$1 digitaldaemon.com>, Steve Strand says...
Can the compiler handle template friends? The code below results in a

..
template<class T>
class vector {
    T data[4];
public:
    vector(T k) {for (int j=0; j<4; ++j) data[j]= k;}
    friend T getitem(const vector<T>& vref, int j);

template <class T1> friend T1 getitem(const vector<T1>& vref, int j);
};

template<class T>
T getitem(const vector<T>& vref, int j)

template<class T1> T1 getitem(const vector<T1>& vref, int j)
{return vref.data[j];}

int main()
{
vector<int> vint(1);
int j= getitem(vint,1);
}

Richard
Feb 25 2003
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
Looks like a compiler bug. -Walter
Feb 25 2003
parent reply Richard Grant <fractal clark.net> writes:
In article <b3h7nr$1oj3$2 digitaldaemon.com>, Walter says...
Looks like a compiler bug. -Walter

I don't think so. One declares a non-template global function that is a "friend" of the template class and the other defines a global function template - that is not a friend of the template class (14.5.3-1). I was kind of in a rush when I posted the correction.. you could actually just change the friend declaration like: template <class T> friend T getitem(const vector<T>& vref, int j); and leave everything else the same. Richard
Feb 26 2003
next sibling parent "Walter" <walter digitalmars.com> writes:
"Richard Grant" <fractal clark.net> wrote in message
news:b3i7ul$29u2$1 digitaldaemon.com...
 In article <b3h7nr$1oj3$2 digitaldaemon.com>, Walter says...
Looks like a compiler bug. -Walter

I don't think so. One declares a non-template global function that is a "friend" of the

 class and the other defines a global function template - that is not a

 the template class (14.5.3-1).

 I was kind of in a rush when I posted the correction.. you could actually

 change the friend declaration like:

 template <class T> friend T getitem(const vector<T>& vref, int j);

 and leave everything else the same.

Thanks for the correction!
Feb 26 2003
prev sibling next sibling parent reply "Steve Strand" <snstrand attbi.com> writes:
Thank you Richard Grant. Your idea does fix all my template friend
problems.

The language standard seems to hold open the possibility that a
non-template function could be a friend of all classes derived from a
template class. I am unable to  devise an example of this. Such a
friend function could not take any arguments pointing to an instance of
the class or refer to any static class members so what is the point of
making it a friend? Even trying to bring an enum declared in the class
scope into the friend function scope does not work with Digital Mars
C++. Is the standard illogical or am I overlooking something?

Steve Strand
Feb 26 2003
parent Richard Grant <fractal clark.net> writes:
In article <b3j5lp$d3$1 digitaldaemon.com>, Steve Strand says...

The language standard seems to hold open the possibility that a
non-template function could be a friend of all classes derived from a
template class. I am unable to  devise an example of this. Such a
friend function could not take any arguments pointing to an instance of
the class or refer to any static class members so what is the point of
making it a friend?

Actually, I think it says that you can do like: friend T getitem(const vector<T>& vref, int j); And that for each specialization of the class template vector, there can be defined a getitem function that will be a friend to the specialization, but then you must define the function to match the template specialization like: int getitem(const vector<int>& vref, int j) { return 0; } But since I have not had the opportunity to use specializations in this context, I'll need to check on that.
Even trying to bring an enum declared in the class
scope into the friend function scope does not work with Digital Mars
C++. Is the standard illogical or am I overlooking something?

Got an example? Richard
Feb 26 2003
prev sibling parent reply "Jim Jennings" <jwjenn mindspring.com> writes:
"Richard Grant" <fractal clark.net> wrote in message
news:b3i7ul$29u2$1 digitaldaemon.com...
 In article <b3h7nr$1oj3$2 digitaldaemon.com>, Walter says...
Looks like a compiler bug. -Walter

I don't think so. One declares a non-template global function that is a "friend" of the template class and the other defines a global function template - that is not a friend of the template class (14.5.3-1). I was kind of in a rush when I posted the correction.. you could actually just change the friend declaration like: template <class T> friend T getitem(const vector<T>& vref, int j); and leave everything else the same. Richard

Richard & Walter, I know you are not in the business of worrying about other compilers, but I tried this program on g++ (mingw) and Borland, and neither of them would compile it. dmc does. Executing g++.exe... ./* .... clip ...*/ C:/Dev-Cpp/Worktemp/template.cpp:9: declaration of `class T' C:/Dev-Cpp/Worktemp/template.cpp:4: shadows template parm `class T' Execution terminated Borland bcc32 says this:
 MAKE Version 5.2  Copyright (c) 1987, 2000 Borland
  C:\borland\bcc55\bin\BCC32 -c -q -O1 -v-  -D_WINVER=0x0400  -D_WIN32_WINNT=

 .\template.cpp:

* inline ! Fatal F1004 .\template.cpp 9: Internal compiler error at 0x480d6e with bas * e 0x400000 in function main() ! Fatal F1004 .\template.cpp 9: Internal compiler error in function main()
 ** error 1 ** deleting .\template.obj

Will D have this house of mirrors called templates? Sometimes I think that the only people profiting from C++ are book authors and AWL. Jim
Feb 26 2003
next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Jim Jennings" <jwjenn mindspring.com> wrote in message
news:b3jhvj$8s8$1 digitaldaemon.com...
 Richard & Walter,
 I know you are not in the business of worrying about other compilers, but

 neither of them would compile it. dmc does.

Cool!
 Will D have this house of mirrors called templates?

It already does have it. But take a look, it has the power of C++ templates with perhaps only one tenth of the complexity, weird cases, strange interactions, etc.
 Sometimes I think that the only people profiting from C++ are book authors

 AWL.

Templates are too powerful a feature to ignore. But I also think they should be used with great caution - most of the uses I see for it are a poor tradeoff for the maintenance grief.
Feb 27 2003
parent reply "Jim Jennings" <jwjenn mindspring.com> writes:
"Walter" <walter digitalmars.com> wrote in message
news:b3kojl$uqg$2 digitaldaemon.com...
 Will D have this house of mirrors called templates?

It already does have it. But take a look, it has the power of C++ templates with perhaps only one tenth of the complexity, weird cases, strange interactions, etc.

OK, get ready for the posts. jwj
Feb 27 2003
parent "Walter" <walter digitalmars.com> writes:
"Jim Jennings" <jwjenn mindspring.com> wrote in message
news:b3l6t5$190t$1 digitaldaemon.com...
 OK, get ready for the posts.

I've got my shields up!
Feb 27 2003
prev sibling parent Richard Grant <fractal clark.net> writes:
In article <b3jhvj$8s8$1 digitaldaemon.com>, Jim Jennings says...

I know you are not in the business of worrying about other compilers, but I
tried this program on g++ (mingw) and Borland, and
neither of them would compile it. dmc does.

This should make them all pretty happy.. template <class T> class A; template <class U> void fn(A<U>& a); template <class T> class A { int i; template <class U> friend void fn(A<U>& a); }; template <class U> void fn(A<U>& a) { a.i = 1; } int main() { A<int> a; fn(a); } Richard
Feb 27 2003