2

I have a template class MGraph<T>with a member function print_relation and a friend function which is ostream& operator<<(ostream& os, const MGraph<T>& other)

I follwed the instructions here and wrote this code:

template<class T>
ostream& MGraph<T>::print_relation(ostream& os) const
{
    for (VertexId i = 0; i < max_size; i++)
    {
        for (VertexId j = 0; j < max_size; j++)
        {
            os << relation[i][j] << ' ';
        }
        os << endl;
    }
    return os;
}
...
template<class T>
ostream& operator<<(ostream& os, const MGraph<T>& other)
{
    os << other.print_relation(os);
    return os;
}

I get the following error when compiling: 1>main.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class MGraph<bool> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$MGraph@_N@@@Z) referenced in function "void __cdecl exec<bool>(class MGraph<bool> *)" (??$exec@_N@@YAXPAV?$MGraph@_N@@@Z)

It appears 4 times, once for every data type (int, char, double, bool).

What did I do wrong?

Community
  • 1
  • 1
asaf92
  • 1,557
  • 1
  • 19
  • 30
  • Where did you put the definition (implementation) of the functions, in a source file or a header file? – Some programmer dude May 07 '16 at 12:12
  • In a header file which is included – asaf92 May 07 '16 at 12:13
  • You typically get errors like that if you put the implementation of templated classes and functions in source files. Also see ["Why can templates only be implemented in the header file?"](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file). – Some programmer dude May 07 '16 at 12:19

1 Answers1

1

In your overload of operator<<, you are doing this

os << other.print_relation(os);

And since MGraph<T>::print_relation returns std::ostream&, that is not valid. operator<< is not overloaded in such way, that it takes std::ostream& on RHS.

So, just remove the os <<.

template<class T>
ostream& operator<<(ostream& os, const MGraph<T>& other)
{
    other.print_relation(os);
    return os;
}
Zereges
  • 5,139
  • 1
  • 25
  • 49