Title
Evaluation of friends of templates
Status
cd1
Section
13.7.5 [temp.friend]
Submitter
John Spicer

Created on 2001-12-19.00:00:00 last changed 189 months ago

Messages

Date: 2003-10-15.00:00:00

[Voted into WP at October 2003 meeting.]

Date: 2002-10-15.00:00:00

Proposed resolution (October 2002):

Change section 13.7.5 [temp.friend] paragraph 5 from:

When a function is defined in a friend function declaration in a class template, the function is defined at each instantiation of the class template. The function is defined even if it is never used. The same restrictions on multiple declarations and definitions which apply to non-template function declarations and definitions also apply to these implicit definitions. [Note: if the function definition is ill-formed for a given specialization of the enclosing class template, the program is ill-formed even if the function is never used. ]
to:
When a function is defined in a friend function declaration in a class template, the function is instantiated when the function is used. The same restrictions on multiple declarations and definitions that apply to non-template function declarations and definitions also apply to these implicit definitions.
Note the change from "which" to "that" in the last sentence.

Date: 2001-12-19.00:00:00

13.7.5 [temp.friend] paragraph 5 says:

When a function is defined in a friend function declaration in a class template, the function is defined at each instantiation of the class template. The function is defined even if it is never used. The same restrictions on multiple declarations and definitions which apply to non-template function declarations and definitions also apply to these implicit definitions. [Note: if the function definition is ill-formed for a given specialization of the enclosing class template, the program is ill-formed even if the function is never used. ]

This means that the following program is invalid, even without the call of f(ai):

  template <class T> struct A {
    friend void f(A a) {
      g(a);
    }
  };
  int main()
  {
    A<int> ai;
  // f(ai);  // Error if f(ai) is actually called
  }

The EDG front end issues an error on this case even if f(ai) is never called. Of the compilers I tried (g++, Sun, Microsoft, Borland) we are the only ones to issue such an error.

This issue came up because there is a library that either deliberately or accidentally makes use of friend functions that are not valid for certain instantiations.

The wording in the standard is the result of a deliberate decision made long ago, but given the fact that most implementations do otherwise it raises the issue of whether we did the right thing.

Upon further investigation, the current rule was adopted as the resolution to issue 6.47 in my series of template issue papers. At the time the issue was discussed (7/96) most compilers did evaluate such friends. So it seems that a number of compilers have changed their behavior since then.

Based on current practice, I think the standard should be changed to evaluate such friends only when used.

History
Date User Action Args
2008-10-05 00:00:00adminsetstatus: wp -> cd1
2004-04-09 00:00:00adminsetmessages: + msg1023
2003-11-15 00:00:00adminsetstatus: ready -> wp
2003-04-25 00:00:00adminsetstatus: review -> ready
2002-11-08 00:00:00adminsetmessages: + msg742
2002-11-08 00:00:00adminsetstatus: open -> review
2001-12-19 00:00:00admincreate