2013-04-19 4 views
0

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

namespace A{ 

    template<class T,unsigned DIM> 
    class CMyTable{ 
     ... 
      public: 
      template<class T,unsigned DIM> 
      friend std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec); 
     }  

    }; 

} 

Исходная задача была, чтобы получить мой оператор < < вне пространства имен А.

Я попытался это решение: How do I define friends in global namespace within another C++ namespace?

namespace A{ 

    template<class T,unsigned DIM> 
    class CMyTable; 
} 

template<class T,unsigned DIM> 
std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec); 

namespace A{ 

    template<class T,unsigned DIM> 
    class CMyTable{ 
     ... 
      public: 
      template<class T,unsigned DIM> 
      friend std::ostream& ::operator<<(std::ostream& s, const CMyTable<T,DIM>& vec); 
     }  

    }; 

} 

template<class T,unsigned DIM> 
std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec){ 
// [...] 
} 

Я получил эту ошибку: ошибка C2063: «оператор < < ': не функция внутри объявления класса.

public: 
template<class T,unsigned DIM> 
friend std::ostream& ::operator<<(std::ostream& s, const CMyTable<T,DIM>& 

У кого-нибудь есть идеи?

Спасибо.

ответ

0

Если перегрузка ostream должен be friend (нуждается в доступе к защищенным членам), затем определите его в строке, чтобы использовать аргументы шаблона, переданные классу.

namespace A{ 

    template<class T,unsigned DIM> 
    class CMyTable{ 
     ... 
     public: 
     // template<class T,unsigned DIM> // This will shadow otherwise 
     friend std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec) { 
     // [...] 
     } 
    }; 
} 

В противном случае полностью удалить свое заявление из класса и namesapce и просто определить его вне как шаблонную перегрузку.

Помните, что не нужно быть другом, если ему не нужен доступ к закрытым или защищенным элементам.

namespace A{ 
    template<class T,unsigned DIM> 
    class CMyTable{ 
    ... 
     public: 
    }; 
} 



template<class T,unsigned DIM> 
std::ostream& operator<<(std::ostream& s, const A::CMyTable<T,DIM>& vec){ 
// [...] 
} 

Третий вариант держать его друга, но определить его в пространство имен

namespace A{ 

    template<class T,unsigned DIM> 
    class CMyTable{ 
     public: 
      int i; 

     template<class V,unsigned E> 
     friend std::ostream& operator<<(std::ostream& s, const CMyTable<V,E>& vec); 
    }; 

}; 
// 
// 

namespace A{ 

    template<class T,unsigned DIM> 
    std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec) { 
     s << vec.i; 
    } 

} 
+0

Спасибо за ваш ответ. Но мне нужен мой метод, чтобы быть другом. Я просто не хочу определять аксессоров (даже const) в моем классе. – Haimo

+0

@ Хаймо, тогда в чем проблема с определением встроенного (внутри класса)? – stardust

+0

Я хочу получить доступ к оператору в глобальном пространстве имен. – Haimo

0

оператор Выход интерфейс класса действительно, так, по логике вещей, он должен находиться в пространстве имен, в котором объявлен класс, но сделать код работы, вы можете использовать

namespace A{ 

    template<class T,unsigned DIM> 
    class CMyTable; 
} 

// friend is not correct here. 
template<class T,unsigned DIM> 
/*friend*/ std::ostream& operator<<(std::ostream& s, const A::CMyTable<T,DIM>& vec); 

namespace A{ 

    template<class T,unsigned DIM> 
    class CMyTable{ 
     ... 
      public: 
      // choose another names of template pars. 
      // or use 
      //friend std::ostream& (::operator << <>)(std::ostream& s, 
      //const CMyTable<T, DIM>&); 
      /*template<class T,unsigned DIM>*/ 
      template<class U, unsigned D> 
      friend std::ostream& (::operator <<)(std::ostream&, 
      const CMyTable<U,D>&); 
     }; 
} 

template<class T,unsigned DIM> 
std::ostream& operator<<(std::ostream& s, const A::CMyTable<T,DIM>& vec){ 
// [...] 
} 
+0

Для друга, это была ошибка в сообщении. Я редактировал сообщение. Я изменил имена аргументов шаблона, но все же получил ту же ошибку: «operator <<» не является функцией. – Haimo

+0

@ Хаймо посмотрите на код хорошо ... Примечание: 'friend std :: ostream & ** (** :: operator << **) **' – ForEveR

+0

Извините, я на самом деле скопировал/вставлял ваш код. Поэтому я добавил круглые скобки. Но все еще не работает ... – Haimo

Смежные вопросы