# C++ programmers, help me please!

**URL:** https://boards.straightdope.com/t/c-programmers-help-me-please/300427
**Category:** Factual Questions
**Created:** [April 21, 2005, 3:41pm UTC](https://boards.straightdope.com/t/c-programmers-help-me-please/300427 "2005-04-21T15:41:37Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![Capt.Ridley\_s\_Shooting\_Party](https://avatars.discourse-cdn.com/v4/letter/c/cc9497/32.png) [@Capt.Ridley\_s\_Shooting\_Party](https://boards.straightdope.com/u/Capt.Ridley_s_Shooting_Party)
#### Post date: [April 21, 2005, 3:41pm UTC](https://boards.straightdope.com/t/c-programmers-help-me-please/300427/1 "2005-04-21T15:41:37Z")

</div>

I used to know this, but too much Java has stunted me and I can’t find the answer anywhere online.

I’m writing a templated class which I would like to override the “\<\<” operator so I can use it via the standard output streams. I’ve defined the operator to be a friend of my class in the class definition and I’ve overloaded the operator. This compiles fine, but when I come to use it, it won’t link! I get the error:

```auto

1>angle.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl mulligan::maths::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > const &,class mulligan::maths::angle<float> const &)" (??6maths@mulligan@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@ABV23@ABV?$angle@M@01@@Z) referenced in function _main
1>Debug\SoftwareEngine.exe : fatal error LNK1120: 1 unresolved externals

```

And I cannot work out why.  
Here’s the definition and declaration of the relevant function:

```auto

friend std::ostream& operator << (const std::ostream& stream, const angle<t>& a);

```

and

```auto

		template<typename t>
		std::ostream& operator << (const std::ostream& stream, const angle<t>& a)
		{
			switch(a._current_represenation)
			{
			case ANGLE_TYPE_DEGREES:
				stream << "mulligan.maths.angle<> : " << a._angle << " degrees.";
				break;
			case ANGLE_TYPE_RADIANS:
				stream << "mulligan.maths.angle<> : " << a._angle << " radians.";
				break;
			}
			return stream;
		}

```

Any help is appreciated, thanks.

---

<div class="post-metadata">

### Author: ![ultrafilter](https://avatars.discourse-cdn.com/v4/letter/u/3d9bf3/32.png) [@ultrafilter](https://boards.straightdope.com/u/ultrafilter)
#### Post date: [April 21, 2005, 3:45pm UTC](https://boards.straightdope.com/t/c-programmers-help-me-please/300427/2 "2005-04-21T15:45:13Z")

</div>

The body of a template function has to be included in any source files that you intend to use it in. Do you have it sitting in its own file like any other code?

---

<div class="post-metadata">

### Author: ![ultrafilter](https://avatars.discourse-cdn.com/v4/letter/u/3d9bf3/32.png) [@ultrafilter](https://boards.straightdope.com/u/ultrafilter)
#### Post date: [April 21, 2005, 3:50pm UTC](https://boards.straightdope.com/t/c-programmers-help-me-please/300427/3 "2005-04-21T15:50:35Z")

</div>

btw, if you’re only using the template argument to differentiate between degrees and radians, it’s really overkill. You could have a class, angle, with a pure virtual function print(), and an operator \<\< that takes an angle a and just calls a.print(). Have subclasses for each representation, and you’re good to go. That gets you around the template link errors quite handily.

---

<div class="post-metadata">

### Author: ![Capt.Ridley\_s\_Shooting\_Party](https://avatars.discourse-cdn.com/v4/letter/c/cc9497/32.png) [@Capt.Ridley\_s\_Shooting\_Party](https://boards.straightdope.com/u/Capt.Ridley_s_Shooting_Party)
#### Post date: [April 21, 2005, 4:05pm UTC](https://boards.straightdope.com/t/c-programmers-help-me-please/300427/4 "2005-04-21T16:05:21Z")

</div>

Thanks. I originally had the body of the operator in my angle class source file. I moved it out to the angle class header, but it still gives the same linking error. Is this what you meant?

BTW: the template parameter specifies what data type the angle is stored as. Overkill, I know, but I want to get used to templates again after using Java fopr so long.

---

<div class="post-metadata">

### Author: ![ultrafilter](https://avatars.discourse-cdn.com/v4/letter/u/3d9bf3/32.png) [@ultrafilter](https://boards.straightdope.com/u/ultrafilter)
#### Post date: [April 21, 2005, 4:08pm UTC](https://boards.straightdope.com/t/c-programmers-help-me-please/300427/5 "2005-04-21T16:08:13Z")

</div>

That is the right approach. If you have precompiled headers turned on, try doing a full rebuild.

---

<div class="post-metadata">

### Author: ![Omphaloskeptic](https://avatars.discourse-cdn.com/v4/letter/o/bcef8e/32.png) [@Omphaloskeptic](https://boards.straightdope.com/u/Omphaloskeptic)
#### Post date: [April 21, 2005, 6:40pm UTC](https://boards.straightdope.com/t/c-programmers-help-me-please/300427/6 "2005-04-21T18:40:55Z")

</div>

One problem I see is that the input stream is declared a const ostream&, while the return value is a (non-const) ostream&. This ought to give you a compile-time error, AFAICT, not the link error you’re getting now (something like "invalid initialization of reference of type ‘std:: ostream&’ from expression of type ‘const std::basic\_ostream’ "). The input should be a non-const ostream&, since writing to an ostream changes its internal state.

Is the template function defined in the correct namespace (mulligan::maths:: )? Could you show an example of the usage of operator\<\< that’s breaking it?

One more thing you could try: remove the templating code (replace the templated classes and functions with a single instantiation) and see if it works then. This will tell you if your problem is with one of the template specifiers or with the basic class structure, and the errors are sometimes easier to decipher with less templating.

I agree with **ultrafilter** on the full rebuild if there are precompiled headers, too.

---

<div class="post-metadata">

### Author: ![ZenBeam](https://avatars.discourse-cdn.com/v4/letter/z/3ab097/32.png) [@ZenBeam](https://boards.straightdope.com/u/ZenBeam)
#### Post date: [April 22, 2005, 5:28pm UTC](https://boards.straightdope.com/t/c-programmers-help-me-please/300427/7 "2005-04-22T17:28:01Z")

</div>

Do you have the definition of the ostream& operator _before_ your class definition? e.g.

```auto

template <class T> class angle;

std::ostream& operator << (const std::ostream& stream, const angle<t>& a)
{
...
}

template <class T> class angle
{
....
  friend std::ostream& operator << (const std::ostream& stream, const angle<t>& a);
}

```

You need to have the function visible before you can declare it a friend. (My understanding is) this is required by the standard, but wasn’t enforced in earlier compilers.

---

<div class="post-metadata">

### Author: ![ultrafilter](https://avatars.discourse-cdn.com/v4/letter/u/3d9bf3/32.png) [@ultrafilter](https://boards.straightdope.com/u/ultrafilter)
#### Post date: [April 22, 2005, 5:29pm UTC](https://boards.straightdope.com/t/c-programmers-help-me-please/300427/8 "2005-04-22T17:29:01Z")

</div>

That would cause a compiler error, not a linker one.

---

<div class="post-metadata">

### Author: ![ZenBeam](https://avatars.discourse-cdn.com/v4/letter/z/3ab097/32.png) [@ZenBeam](https://boards.straightdope.com/u/ZenBeam)
#### Post date: [April 22, 2005, 6:47pm UTC](https://boards.straightdope.com/t/c-programmers-help-me-please/300427/9 "2005-04-22T18:47:37Z")

</div>

From [a C++ FAQ for the Sun compiler](http://www.sgr.nada.kth.se/unix/software/forte_7/mr/READMEs/c++_faq.html#w1) (bolding mine)

> [@](#):
>
> The following test case compiles and links without errors with the C++ 5.0 compiler but causes **link-time** errors with later versions of the compiler

Unfortunately, **+MDI** , I don’t think this will solve your problem. I had the same problem with my code when compiling on the Sun platform, and was able to fix it with the help of the link above. I thought I had it working on my PC compiler as well, but apparently I just wasn’t testing that bit of code. At least I’m able to reproduce your error. 😉

---

<div class="post-metadata">

### Author: ![ZenBeam](https://avatars.discourse-cdn.com/v4/letter/z/3ab097/32.png) [@ZenBeam](https://boards.straightdope.com/u/ZenBeam)
#### Post date: [April 22, 2005, 6:59pm UTC](https://boards.straightdope.com/t/c-programmers-help-me-please/300427/10 "2005-04-22T18:59:28Z")

</div>

Got it (I thought I had this working once). You need template \<class T\> in front of the friend declaration:

```auto

template <class T> class angle
{
....
  template <class T>
  friend std::ostream& operator << (const std::ostream& stream, const angle<T>& a);
}

```

On my Visual Studio .NET 2003 compiler, it doesn’t matter if the definition is before the class definition.

---

<div class="post-metadata">

### Author: ![Capt.Ridley\_s\_Shooting\_Party](https://avatars.discourse-cdn.com/v4/letter/c/cc9497/32.png) [@Capt.Ridley\_s\_Shooting\_Party](https://boards.straightdope.com/u/Capt.Ridley_s_Shooting_Party)
#### Post date: [April 23, 2005, 7:14pm UTC](https://boards.straightdope.com/t/c-programmers-help-me-please/300427/11 "2005-04-23T19:14:52Z")

</div>

Sorry it’s taken so long to get back to you. I appreciate the input, and I’ve tried a few things which have been suggested, and I’ve finally got it working correctly.

FWIW, I’m using MS’s latest compiler (MS C++ 2005 Beta 2). It works exactly as ZenBeam’s link states, apart from I needed to swap the global namespace lookup for mulligan::maths.

The template line that ZenBeam has before his friend operator declaration is redundant on the new compiler (it compiles, links and runs fine without it).

Thanks for all the suggestions and advice.
