Функция друга не может определить тип в параметре - PullRequest
2 голосов
/ 24 октября 2019

В моем заголовочном файле vector.h у меня есть:

template <typename T>
class Vector{
private:
    int sz:
    T* buf;
public:
//member functions all the way down
friend ostream& operator << (ostream & o, const Vector & v);
};

В моем файле vector.cpp есть следующее:

#include "vector.h"
using namespace std;
//member functions defined

std::ostream& operator << (std::ostream & o, const Vector & v){
 return o;
}

Я получаю сообщение об ошибке компилятора о том, что "Vector "- это имя неизвестного типа в строке, где определен оператор <<. Может ли кто-нибудь помочь мне понять, почему это так? Мне не разрешено изменять заголовочный файл. </p>

Ответы [ 2 ]

2 голосов
/ 24 октября 2019

Реализация функции operator<< как

std::ostream& operator << (std::ostream & o, const Vector & v){
   return o;
}

не работает, поскольку Vector является шаблоном, а не типом. Вы должны будете использовать:

template <typename T>
std::ostream& operator << (std::ostream & o, const Vector<T> & v){
   return o;
}

Однако, это покажет больше проблем. Обратите внимание, что вышеприведенная реализация делает вышеупомянутую operator<< функцией шаблоном, а не функцией. Объявление friend внутри класса не использует шаблон функции. Он использует функцию. Это не правильно.

Чтобы сделать это правильно, вам необходимо:

  1. Объявить шаблон класса.
  2. Объявить шаблон функции.
  3. Объявите конкретную реализацию шаблона функции другом шаблона класса.

Вот минимальная программа, которая работает для меня.

#include <iostream>

// Delcare the class template
template <typename T> class Vector;

// Declare the function template
template <typename T>
std::ostream& operator << (std::ostream & o, const Vector<T> & v);

template <typename T>
class Vector{
   private:
      int sz;
      T* buf;
   public:
      Vector(int s) : sz(s) {}

      // Friend declaration that uses a specific instantiation of the function template.
      // Note that operator<< <int> is a function of Vector<int> only, not that
      // of Vector<double> or any other instantiaton of Vector.
      friend std::ostream& operator<< <T> (std::ostream & o, const Vector & v);
};

// Implement the function template.
template <typename T>
std::ostream& operator << (std::ostream & o, const Vector<T> & v){
   return (o << v.sz);
}

int main()
{
   Vector<int> v(10);
   std::cout << v << std::endl;
}

Вы сказали,

Мне не разрешено изменять заголовочный файл.

К сожалению. Возможно, вы сможете убедить своего учителя передумать или обновить файл .h, чтобы можно было внедрить чистое решение.

1 голос
/ 24 октября 2019

Ваш вектор является шаблоном класса. Следовательно, компилятор не знает Vector. Он знает только Vector<...someType...>.

Так что вы можете написать что-то вроде этого

std::ostream& operator << (std::ostream & o, const Vector<int> & v){
 return o;
}

С этой функцией минимальный рабочий пример, который не изменяет заголовок, будет:

template <typename T>
class Vector
{
private:
    int sz;
    T* buf;

public:
    // member functions all the way down
    friend std::ostream& operator<<(std::ostream& o, const Vector& v);
};


std::ostream& operator<<(std::ostream& o, const Vector<int>& v)
{
    return o;
}

int main()
{
    Vector<int> a;
    std::cout << a << std::endl;
}

Однако, чтобы получить общего оператора вне потока, вы должны использовать другой шаблон:

template <typename T>
std::ostream& operator<<(std::ostream& o, const Vector<T>& v)
{
    return o;
}

В этом случае реализация должна оставаться в заголовке. В противном случае вы можете использовать его только в своем Vector.cpp, потому что шаблоны не производят никакого кода, пока они не будут созданы. В результате каждый файл, который хочет использовать оператор, должен знать реализацию шаблона для генерации необходимого кода.

Кроме того, для правильной работы необходимо настроить объявление друга:

template <typename T2>
friend std::ostream& operator<<(std::ostream& o, const Vector<T2>& v);

Чтобы найти более разумный способ настроить объявление друга, взгляните на ответ Р. Саху

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...