In this program, Beta::Gamma declares ::Alpha as a friend, but the friendship
does not work.

===

[EMAIL PROTECTED]:~/exp-friend$ cat z1.cc
template <typename T>
void Alpha(T* a) { a->Delta(); }

namespace Beta {

class Gamma {
 public:
  template <typename T> friend void ::Alpha(T*);

 private:
  void Delta();
};

}

int main() {
  Beta::Gamma* a = new Beta::Gamma;
  ::Alpha(a);
}

bash: /home/mec/gcc-4.2.1/install/bing++: No such file or directory
[EMAIL PROTECTED]:~/exp-friend$ /home/mec/gcc-4.2.1/install/bin/g++ -O2 -Wall -c
z1.cc
z1.cc: In function 'void Alpha(T*) [with T = Beta::Gamma]':
z1.cc:18:   instantiated from here
z1.cc:11: error: 'void Beta::Gamma::Delta()' is private
z1.cc:2: error: within this context

[EMAIL PROTECTED]:~/exp-friend$ /home/mec/gcc-4.2.2/install/bin/g++ -O2 -Wall -c
z1.cc
z1.cc: In function 'void Alpha(T*) [with T = Beta::Gamma]':
z1.cc:18:   instantiated from here
z1.cc:11: error: 'void Beta::Gamma::Delta()' is private
z1.cc:2: error: within this context

[EMAIL PROTECTED]:~/exp-friend$ /home/mec/gcc-4.3.0/install/bin/g++ -O2 -Wall -c
z1.cc
z1.cc: In function 'void Alpha(T*) [with T = Beta::Gamma]':
z1.cc:18:   instantiated from here
z1.cc:11: error: 'void Beta::Gamma::Delta()' is private
z1.cc:2: error: within this context
[EMAIL PROTECTED]:~/exp-friend$ 

===

In this program, Beta::Gamma declares the specialization ::Alpha<Beta::Gamma>
as a friend.  This works.

[EMAIL PROTECTED]:~/exp-friend$ cat z3.cc
template <typename T>
void Alpha(T* a) { a->Delta(); }

namespace Beta {

class Gamma {
 public:
  friend void ::Alpha<Beta::Gamma>(Beta::Gamma*);

 private:
  void Delta();
};

}

int main() {
  Beta::Gamma* a = new Beta::Gamma;
  ::Alpha(a);
}

[EMAIL PROTECTED]:~/exp-friend$ /home/mec/gcc-4.2.1/install/bin/g++ -O2 -Wall -c
z3.cc
[EMAIL PROTECTED]:~/exp-friend$ /home/mec/gcc-4.2.2/install/bin/g++ -O2 -Wall -c
z3.cc
[EMAIL PROTECTED]:~/exp-friend$ /home/mec/gcc-4.3.0/install/bin/g++ -O2 -Wall -c
z3.cc
[EMAIL PROTECTED]:~/exp-friend$

===

I think z1.cc is valid, per this clause from [temp.friend]:

"A template friend declaration specifies that all specializations of that
template, whether they are implicitly instantiated (14.7.1), partially
specialized (14.5.4) or explicitly specialized (14.7.3) are friends of the
class containing the template friend declaration.

I suspect it's a bug with the namespace part of "template <typename T> friend
void ::Alpha(T*);".


-- 
           Summary: befriending a whole template in another namespace fails
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: mec at google dot com
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35927

Reply via email to