Created on 1997-11-07.00:00:00 last changed 319 months ago
Rationale (04/99): The first sub-issue reflects wording that was changed to address the concern before the IS was issued. A close and careful reading of the Standard already leads to the conclusion that the example in the second sub-issue is ill-formed, so no change is needed.
Issue 1
Paragraph 1 says that a friend of a class template can be a template. Paragraph 2 says: A friend template may be declared within a non-template class. A friend function template may be defined within a non-template class.
I'm not sure what this wording implies about friend template definitions within template classes. The rules for class templates and normal classes should be the same: a function template can be declared or defined, but a class template can only be declared in a friend declaration.
Issue 2
Paragraph 4 says: When a function is defined in a friend function declaration in a class template, the function is defined when the class template is first instantiated. I take it that this was intended to mean that a function that is defined in a class template is not defined until the first instantiation. I think this should say that a function that is defined in a class template is defined each time the class is instantiated. This means that a function that is defined in a class template must depend on all of the template parameters of the class template, otherwise multiple definition errors could occur during instantiations. If we don't have a rule like this, compilers would have to compare the definitions of functions to see whether they are the same or not. For example:
template <class T> struct A {
friend int f() { return sizeof(T); }
};
A<int> ai;
A<long> ac;
I hope we would all agree that this program is ill-formed, even if long
and int have the same size.
From Bill Gibbons:
[1] That sounds right.
[2] Whenever possible, I try to treat instantiated class templates as if they were ordinary classes with funny names. If you write:
struct A_int {
friend int f() { return sizeof(int); }
};
struct A_long {
friend int f() { return sizeof(long); }
};
it is a redefinition (which is not allowed) and an ODR violation. And if
you write:
template <class T, class U> struct A {
friend int f() { return sizeof(U); }
};
A<int,float> ai;
A<long,float> ac;
the corresponding non-template code would be:
struct A_int_float {
friend int f() { return sizeof(float); }
};
struct A_long_float {
friend int f() { return sizeof(float); }
};
then the two definitions of "f" are identical so there is no ODR
violation, but it is still a redefinition. I think this is just an editorial
clarification.
Rationale (04/99): The first sub-issue reflects wording that was changed to address the concern before the IS was issued. A close and careful reading of the Standard already leads to the conclusion that the example in the second sub-issue is ill-formed, so no change is needed.
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 1999-09-14 00:00:00 | admin | set | messages: + msg197 |
| 1999-09-14 00:00:00 | admin | set | status: drafting -> nad |
| 1997-11-07 00:00:00 | admin | create | |