Как объявить оператор << для внутреннего класса - PullRequest
0 голосов
/ 29 июня 2011
//cannot declare operator<<(...) here:
//forward declarations:
class External;

template<class T, class Y>
class External::Internal;

template<class T, class Y>
std::ostream& operator<<(std::ostream& out, const External::Internal<T,Y>&);

class External
{
    template<class T, class Y>
    class Internal
    {};

    Internal data_;

    void print() {
        /*out is a std::ostream*/
        out << data_;
    }
};

template<class T, class Y>
std::ostream& operator<<(std::ostream& out, const External::Internal<T,Y>&)
{ }

Я хочу реализовать operator<< для Internal, но возникает проблема, когда я пытаюсь использовать этот оператор вызова из External: он не видит этот оператор, когда этот оператор объявлен вопределение этого класса, и, кажется, нет способа объявить этот оператор выше этого определения класса.

Ответы [ 6 ]

1 голос
/ 29 июня 2011

Если вы спрашиваете, как определить Internal<>::operator<< как друга, то:

class External
{
  template<class T, class Y>
  class Internal
  {
    friend std::ostream& operator <<(std::ostream& out, const Internal&)
    {
      // impl
      return out;
    }
  };

  Internal<Foo, Bar> data_;

public:
  void print() const
  {
    /*out is a std::ostream*/
    out << data_;
  }
};
1 голос
/ 29 июня 2011

Смысл в использовании предварительных деклараций:

// you promise there will be implementation of this stuff later on:
template<typename T, typename Y>
class External::Internal<T, Y>;

template<typename T, typename Y>
std::ostream& operator<<(std::ostream& out, const External::Internal<T, Y>&);

// now declare your class and operator<< function as normal
class External
{
    template<class T, class Y>
    class Internal
    {
    };

    Internal<Foo, Bar> data_;

    void print()
    {
        // here you can use operator<< with Internal
        out << data_;
    }
};

template<class T, class Y>
std::ostream& operator<<(std::ostream& out,const External::Internal<T, Y>&)
{
}
1 голос
/ 29 июня 2011

Армен ответ будет работать для самого оператора <<.

Однако ваша декларация участника

Internal data_;

тоже неверно, точно так же. Т.е. не хватает шаблонных аргументов для Internal. Таким образом, в дополнение к исправлению реализации вашего оператора, исправьте также объявление вашего члена.

Наконец, помните, что в C ++ вы не можете использовать что-либо, если оно не было объявлено. Использование << во встроенной реализации print нарушает это. Так что вам лучше переставить вещи (или просто объявить их) так, чтобы все, что использовалось, уже было объявлено.

Приветствия & hth.,

1 голос
/ 29 июня 2011
template<class T, class Y>
std::ostream& operator<<(std::ostream& out,const External::Internal<T, Y>&)
                                                 ^^^^^^^^^^        ^^^^^^
{

}

И обязательно объявите эту функцию friend, потому что Internal является приватным в External

Обновление: вот как вы объявляете друга. В вашем определении класса напишите:

template<class T, class Y>
friend  std::ostream& operator <<(std::ostream& out, const External::Internal<T,Y>&)

Поскольку объявление друга является декларацией, это решит проблему с вашим предварительным объявлением.

Обновление: для решения круговой зависимости:

Первый форвард-объявить internal

template<class T, class Y>
class Internal;

тогда объявите друга.

Тогда остальная часть вашего класса должна работать.

0 голосов
/ 29 июня 2011

возникает проблема, когда я пытаюсь использовать этот вызов оператора из External

Не пишите процедурный код внутри определения вашего класса.Только объявления.

Запись в порядке:

  • Определение класса [в заголовке]
  • operator<< [в заголовке]
  • Код, которыйиспользует эти вещи [в исходном файле]
0 голосов
/ 29 июня 2011
template<class T, class Y>
std::ostream& operator<<(std::ostream& out, const External::Internal<T, Y>&)
{
}

External:: ведет себя как пространство имен и требуется, потому что определение operator<< находится вне класса External.

...