Topic: templated friend of non-template class


Author: dtmoore@email.unc.edu (Dave Moore)
Date: 3 Sep 2002 14:50:07 GMT
Raw View
Pete Becker <petebecker@acm.org> wrote in message news:<3D72299E.C6597721@acm.org>...
> Dave Moore wrote:
> >
> > Is there any way to make a declaration inside a non-templated class
> > specifying that, "All classes based on template foo are friends of
> > this class"?.
>
> Nope. A friend must be a function or a class. A template is neither.

     Ok, that clears things up as to why my attempts have failed.  But
I fail to see *why* is it not allowed.  It seems to me that when a
function is trying to access private data from some class foo, the
compiler will ask the question, "Is it (the function) a member or
friend of foo?"  Why not allow templates as friends then?  The attempt
to access private members will first be detected when the template is
instantiated, at which point the compiler has enough information about
the template instantiation to check that it matches with the friend
declaration in the original class.

     At an even more general level, the declaration that something as
"friend" simply provides private namespace access to the "befriended"
item.  From this point of view, the restriction of friends to classes
and functions seems too strong.  Why shouldn't it be allowed to grant
private namespace access to a generic "set" of functions or classes as
well?

     I am no expert in compiler design, but it seems that there is not
much difference between checking these cases for a non-templated
function and for an instantiation of a templated function.  If I am
wrong about this, could someone please enlighten me as to why?  Thanks
in advance,

Dave Moore

P.S.  Just in case you are curious as to why I an so keen on being
able to do such a thing, consider the following:

class foo_input_reader {
  // reads file or terminal input to determine the properties of some
  // objects of the class foo, which has been templated on an integer
  // value to enhance runtime performance
  friend template <int> class foo;
};

class foo_base {
  // Non-templated base class to allow for runtime polymorphism
public:
  virtual void foo_method()=0;
};

template <int i>
class foo : public foo_base {
  foo(const foo_input_reader& f);

  virtual void foo_method() {
    // ...
    // code containing some performance-sensitive use of the parameter
    // i, requiring this particular design decision (as opposed to
    // using an integer member datum
  }
};

int main(int argc, char *argv[]) {
  foo_input_reader input();
  // ...
  //get input
  // ...

  foo_base* f;
  switch (argc) { // artificial example for simplicity
  case 1:
    f = new foo<1>(input);
    break
  case 2:
    f = new foo<2>(input);
    break;

  f.foo_method(); // do whatever
  return 0;
}

In my particular case, the input is quite complex, and so without the
ability to declare a friend template, I am forced either to use a
struct for foo_input_reader (bad design IMHO).  Otherwise I have to
provide a public const "browser" method for each data member of
foo_input_reader that is needed in the ctor for class foo, and this is
quite tedious (25+ accessors), and (again IMHO) unnecessary.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]