6

I'm exploring the boost::iterator_facade and came across this bit of code:

    friend class boost::iterator_core_access;
    template <class> friend class Iterator;

What does the second line mean? I'm familiar with friend classes, but I don't think I've seen template <class> in front of anything before.


Here's the context:

template <class Value>
class node_iter
  : public boost::iterator_facade<
        node_iter<Value>
      , Value
      , boost::forward_traversal_tag
    >
{
 public:
    node_iter()
      : m_node(0) {}

    explicit node_iter(Value* p)
      : m_node(p) {}

    template <class OtherValue>
    node_iter(node_iter<OtherValue> const& other)
      : m_node(other.m_node) {}

 private:
    friend class boost::iterator_core_access;
    template <class> friend class node_iter;

    template <class OtherValue>
    bool equal(node_iter<OtherValue> const& other) const
    {
        return this->m_node == other.m_node;
    }

    void increment()
    { m_node = m_node->next(); }

    Value& dereference() const
    { return *m_node; }

    Value* m_node;
};
typedef impl::node_iterator<node_base> node_iterator;
typedef impl::node_iterator<node_base const> node_const_iterator;
vmrob
  • 2,966
  • 29
  • 40
  • 1
    http://en.cppreference.com/w/cpp/language/friend – chris Jun 06 '14 at 01:22
  • `class node_iter` is a friend to itself here. It looks like this line maybe redundant as a class is a friend to itself by default –  Jun 06 '14 at 01:24

2 Answers2

5

It just means Iterator is a template class with one template parameter. The friendship is granted to all instantiations of Iterator.

Iterator<int> is a friend of the class.

Iterator<bool> is a friend of the class.

...

Iterator<MyClass> is a friend of the class.

You get the idea.

Example Usage

Say you have a class template Foo.

template <typename T> class Foo
{
   public:
      Foo() : data(0) {}
   prvavte:
      T data;
};

When you instantiate the class template using:

Foo<int> a;
Foo<float> b;

you are creating two classes at compile time. Foo<int> does not have access to the private section of Foo<float> and vice versa. That is an inconvenience some times.

You can't do:

b = a;  // If you wanted to pull the data from a and put it in b.

Even if you added an assignment operator to the class,

template <typename T> class Foo
{
   public:
      Foo() : data(0) {}
      template <typename T2> Foo& operator=(Foo<T2> const& rhs)
      {
         this->data = rhs.data;
         return *this;
      }

   private:
      T data;
};

It won't work because Foo<T> doesn't have access to the private sections of Foo<T2>. To get around that you can use a friend declaration.

template <typename T> class Foo
{
   public:
      template <class> friend class Foo;
      Foo() : data(0) {}
      template <typename T2> Foo& operator=(Foo<T2> const& rhs)
      {
         this->data = rhs.data;
         return *this;
      }

   private:
      T data;
};

Now, you can use:

Foo<int> a;
Foo<float> b;
b = a;
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Ah, I think the part I was missing is basically that `template ` contains an unnamed template parameter. I guess that just rarely comes up. – vmrob Jun 06 '14 at 01:33
0

Explicit Instantiation: http://www.cplusplus.com/articles/1C75fSEw/

It allows you to instantiate the template without actually using it.

CRABOLO
  • 8,605
  • 39
  • 41
  • 68
Russell Ormes
  • 525
  • 8
  • 22