↑ ↓ ← → "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);
}
↑ ↓ ← → 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
↑ ↓
← → "Walter" <walter digitalmars.com>
writes:
Looks like a compiler bug. -Walter
↑ ↓ ← → 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
↑ ↓ ← → "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!
↑ ↓ ← → "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
↑ ↓ ← → 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
↑ ↓
← → "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
↑ ↓ ← → "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.
↑ ↓ ← → "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
↑ ↓ ← → "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!
↑ ↓
← → 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