3

Possible Duplicate:
overloading friend operator<< for template class

I'm trying to overload operator<< for a template class but I'm getting errors...


Final(fixed) code:

template<class T>
class mytype
{
    T atr;
public:
    mytype();
    mytype(T);
    mytype(mytype&);
    T getAtr() const;
    T& operator=(const T&);
    template<class U> friend ostream& operator<<(ostream&,const mytype<U>&);
};

template<class T>
mytype<T>::mytype()
{
    atr=0;
}

template<class T>
mytype<T>::mytype(T value)
{
    atr=value;
}

template<class T>
mytype<T>::mytype(mytype& obj)
{
    atr=obj.getAtr();
}


template<class T>
T mytype<T>::getAtr() const
{
    return atr;
}

template<class T>
T& mytype<T>::operator=(const T &other)
{
    atr=other.getAtr();
    return *this;
}

template<class U>
ostream& operator<<(ostream& out,const mytype<U> &obj)
{
    out<<obj.getAtr();
    return out;
}

(All in the header file)


VS2012 errors:

1)

Error 1 error LNK2019: unresolved external symbol "public: __thiscall mytype::mytype(int)" (??0?$mytype@H@@QAE@H@Z) referenced in function _wmain

2)

Error 2 error LNK2019: unresolved external symbol "class std::basic_ostream > & __cdecl operator<<(class std::basic_ostream > &,class mytype const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$mytype@H@@@Z) referenced in function _wmain

3)

Error 3 error LNK1120: 2 unresolved externals


What's wrong with my code?

Community
  • 1
  • 1
Cristi
  • 1,195
  • 6
  • 17
  • 24
  • `_tmain` should probably be just `main` – John Dibling Nov 26 '12 at 18:13
  • 2
    no, visual studio uses _tmain instead of main for C++ console applications – Cristi Nov 26 '12 at 18:16
  • 1
    Every C++ program is required to have a `main` function as the entry point. the fact that you're trying to do this in Windows is orthoganal to the problem you're having. – John Dibling Nov 26 '12 at 18:19
  • 3
    @JohnDibling, so your comment was pretty pointless right here, as it isn't connected with the question at all. – Bartek Banachewicz Nov 26 '12 at 18:20
  • 3
    I'm not an expert to VS as I work under linux, but I also know for a fact that VS uses _tmain, so there's no need for main() per se, and I don't think this is the problem – Moataz Elmasry Nov 26 '12 at 18:20
  • Put your template function definitions in the header. This has been covered many, many times before. – Lightness Races in Orbit Nov 26 '12 at 18:24
  • @BartekBanachewicz: If it helps someone reading this to understand something they didn't understand before, its not pointless. You're comment was also not connected with the question. Is that OK for you but not for me? – John Dibling Nov 26 '12 at 18:26
  • I wouldn't say a thing if you would clarify that your statement is just a general advice and isn't connected to the question itself; right now it's misleading. And **that**'s the point I tried to make. – Bartek Banachewicz Nov 26 '12 at 18:28
  • I agree that my initial comment was just general advice that did not address the actual problem -- that's why it was just a comment & not an answer. I did then try to clarify a bit when OP replied, but given that people seem to take offence by my comment (which was not meant to offend or chide), be patient with me while I try again... – John Dibling Nov 26 '12 at 18:33
  • 2
    Using the Windows-specific `_tmain` function rather than the Standard-mandated `main` function confuses matters slightly. Not everybody is familiar with Windows, but everyone in the [C++] tag is assumed to be speaking about Standard C++. You might get some grief about the Windows-specific construct here, which could stand in the way of getting an actual answer. I'd suggest changing your code to using Standard constructs if the problem you're having isn't specific to Windows. – John Dibling Nov 26 '12 at 18:36
  • @BartekBanachewicz: Is that better? – John Dibling Nov 26 '12 at 18:42
  • Apart from [tag:c++] (`[tag:c++]`) it's perfect :). Please, don't take my response personally, I am also trying to make SO a better place. – Bartek Banachewicz Nov 26 '12 at 18:56

4 Answers4

4

You told the compiler to expect a free non-template function:

friend ostream& operator<<(ostream&,const mytype<T>&);

...but then you defined a function template instead:

template<class T>
ostream& operator<<(ostream& out,const mytype<T> &obj)
{
    out<<obj.getAtr();
    return out;
}

Tell the compiler instead to expect a function template:

template<class T> friend ostream& operator<<(ostream&,const mytype<T>&);
John Dibling
  • 99,718
  • 31
  • 186
  • 324
1

It seems implementation/definition of the constructors is missing.

ypnos
  • 50,202
  • 14
  • 95
  • 141
1

EDIT I see now the question has been updated and the constructors have been defined.

In this case you just need to put your constructor definitions in your header. Another way to do this that some people do is to define an .inl(inline) file and include that at the bottom of your header.

Well you declare the constructor

mytype(T);

But you never actually get around to defining it.

The compiler won't create a default body for the above constructor as it has no idea how to do it.

chollida
  • 7,834
  • 11
  • 55
  • 85
1

You also need to specify template<class T> in the class's declaration of the operator:

template<class T>
class mytype
{
    T atr;
public:
    ...
    T getAtr() const;

    template<class U>
    friend ostream& operator<<(ostream&,const mytype<U>&);
    ...
};

Alternatively, implement the operator inside the class:

template<class T>
class mytype
{
    T atr;
public:
    ...
    T getAtr() const;

    friend ostream& operator<<(ostream&,const mytype<T>&)
    {
        ...
    }

    ...
};

As for the first error, it's probably because you are implementing mytype's constructor in a source file. For template classes, you should implement all methods (and constructors, etc) inside the class.

user1610015
  • 6,561
  • 2
  • 15
  • 18
  • @LightnessRacesinOrbit Sure, but most people don't bother implementing them right below the class definition, they just implement them inside the class. – user1610015 Nov 26 '12 at 18:28
  • That's no reason to mandate it :) Anyway I'd love to see your data on that poll - I and all the people I know implement functions out-of-line even when in the header. – Lightness Races in Orbit Nov 26 '12 at 18:29