Topic: friend specializations of template functions
Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1997/10/20 Raw View
--Multipart_Sun_Oct_19_23:07:55_1997-1
Content-Type: text/plain; charset=US-ASCII
Hi!
I've just come across some doubts I just can't solve by reading and
rereading CD2.
AFAIK, there's a bug in CD2 regarding friend declarations of template
function specializations, but this is another issue.
Given the following code snippet, how would you answer the questions
embedded in the program, according to the expected behavior of a C++
compiler?
--Multipart_Sun_Oct_19_23:07:55_1997-1
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="test.cc"
Content-Transfer-Encoding: 7bit
#include <iostream.h>
// this is version 0, just to make sure foo is a template function
template <typename T>
void foo(T(*)(), T(*)());
template <typename T>
class bar {
// (1) Should this give priviledged access to version 1 and its
// specializations even if version 1 has not been declared yet?
// (2) Should version2 0 and 2 be considered friends or not?
friend void foo<bar<T> >(const bar<T>&, const bar<T>&);
// (3) Should this refer to version 2 only, or to both version 1 and 2?
// friend void foo<>(const bar<T>&, const bar<T>&);
protected:
T f;
public:
bar(const T& f_) : f(f_) {}
};
// this is version 1
template <typename T>
void foo(const T& t1, const T& t2) {
cout << t1.f << ' ' << t2.f << endl;
}
// this is version 2
// (4) is this considered an explicit specialization of version 1?
template <typename T>
void foo(const bar<T>& t1, const bar<T>& t2) {
cout << t1.f << ',' << t2.f << endl;
}
int main() {
bar<int> a(1), b(2);
// call version 2;
foo(a, b); // (5) fail because bar<int>::f is not accessible?
// call version 1; ok
foo<bar<int> >(a, b);
}
--Multipart_Sun_Oct_19_23:07:55_1997-1
Content-Type: text/plain; charset=US-ASCII
I'd answer the questions as follows:
(1) IMO, version 1 should be before this friend declaration. However,
since the actual template function instance is only resolved at
template instantiation time, this may be accepted anyway. The only
strange point of this issue is that a declaration of *any* template
function named foo is required at the declaration point (is it?).
Even an unrelated template function foo will do, but there must be at
least one. Can't this requirement be dropped, allowing one to refer
to foo<> even if there's no valid declarations of foo template
functions yet?
(2) Only version 1 and its specializations should be considered
friends, IMO.
(3) This might affect only version 2, or both 1 and 2, or any other
friend functions that could have been defined that would match the
given declaration. I'd prefer that this affected only the most
specialized version of the template.
(4) IMO, these template functions are unrelated, although version2 is
more specialized than version1. Otherwise, foo<bar<T> > would resolve
to version2, but, IMO, it shouldn't.
(5) Considering that the friend declaration affects only version1, and
that overload resolution selects version2, the instantiation of
foo<int>(const bar<int>&, const bar<int>&) should fail because
bar<int>::f is not accessible.
Thanks in advance for any insights you can provide.
--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil
--Multipart_Sun_Oct_19_23:07:55_1997-1--
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]