# C++ question (templates)

**URL:** <https://boards.straightdope.com/t/c-question-templates/323888>\
**Category:** Factual Questions\
**Created:** [September 28, 2005, 5:57pm UTC](https://boards.straightdope.com/t/c-question-templates/323888 "2005-09-28T17:57:00Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trunk](https://avatars.discourse-cdn.com/v4/letter/t/87869e/32.png) [@Trunk](https://boards.straightdope.com/u/Trunk)\
**Post date:** [September 28, 2005, 5:57pm UTC](https://boards.straightdope.com/t/c-question-templates/323888/1 "2005-09-28T17:57:00Z")

</div>

Now, I know you can’t overload an operator by return type, but can you do this. . .

Let’s say I have a class designed as such. . .

```auto

template <class T>
Trunk
{
   member<T> m;
};

```

Now, I want to write a function like this. . .

```auto

template <class T>
Trunk<T> f()
{
   //something.
   Trunk<T> t;
   //something
   return t;
}

```

And then in the code, I do something like this. . .

```auto

int main()
{
   Trunk<double> d; 
   d = f();
}

```

or

```auto

int main()
{
   Trunk<long> l; 
   l = f();
}

```

BZZZZT!

I can get the function to compile fine, but it doesn’t like the call. Naturally, I can work around it with something like

```auto

template <class T>
void f(Trunk<T>& t)
{	
   //do something
}

```

Then doing this is fine. . .

```auto

Trunk<double> d;
f(d);

```

I can kind of feel why what I’m doing is wrong even though it looks somewhat logical. I think I’m asking the compiler to know what KIND of thing Trunk is going to be at runtime, or soemthing. So,

1. Can I actually do what I’m trying to do with some other syntax?

2. For my own edification, what’s the actual issue here?

---

<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:** [September 28, 2005, 7:06pm UTC](https://boards.straightdope.com/t/c-question-templates/323888/2 "2005-09-28T19:06:57Z")

</div>

> [@Trunk](#):
>
> Now, I know you can’t overload an operator by return type, but can you do this. . .
> 
> [… overloads a template function based on return type…]
> 
> I can get the function to compile fine, but it doesn’t like the call. […]
> 
> I can kind of feel why what I’m doing is wrong even though it looks somewhat logical. I think I’m asking the compiler to know what KIND of thing Trunk is going to be at runtime, or soemthing. So,
> 
> 1. Can I actually do what I’m trying to do with some other syntax?
> 
> 2. For my own edification, what’s the actual issue here?

It seems to me that the issue is the same one you named at the beginning: You’re trying to do ambiguity resolution (here, to create a particular instance of a templated function) based on the return type of the function. This is not permitted in C++; I assume this is because doing so would require the parser to look both inward and outward to try to resolve ambiguities, in contrast to the current method where ambiguities are always resolved from the inside out.

But why don’t you want to do something like

```auto

template <class T>
Trunk
{
   member<T> m;

public:
   void f() { /* do something to *this; */ }
};

int main() {
  Trunk<double> d;
  d.f();
}

```

–that is, since you want a templated function associated with the templated class, just make the function a method of the templated class.

If you really wanted you could make f an overloaded unary operator (e.g., ! ~ + - ++ – \*) to avoid the function-call syntax:

```auto

  void operator~() { /* do something to *this */ }

  // ...

  ~d;

```

---

<div class="post-metadata">

**Author:** ![Trunk](https://avatars.discourse-cdn.com/v4/letter/t/87869e/32.png) [@Trunk](https://boards.straightdope.com/u/Trunk)\
**Post date:** [September 28, 2005, 7:17pm UTC](https://boards.straightdope.com/t/c-question-templates/323888/3 "2005-09-28T19:17:00Z")

</div>

I don’t actually have access to the templated class (in this case, Trunk).

I mean, I have the source code and all, but it’s third party. I’m adding functions that operate on the classes, but i"m not actually adding anything to the classes.

---

<div class="post-metadata">

**Author:** ![TimeWinder](https://avatars.discourse-cdn.com/v4/letter/t/bcef8e/32.png) [@TimeWinder](https://boards.straightdope.com/u/TimeWinder)\
**Post date:** [September 28, 2005, 7:20pm UTC](https://boards.straightdope.com/t/c-question-templates/323888/4 "2005-09-28T19:20:07Z")

</div>

> [@Trunk](#):
>
> 1. Can I actually do what I’m trying to do with some other syntax?
> 
> 2. For my own edification, what’s the actual issue here?

1. No, you’ll need to do something like your second example above; passing the template-typed variable as a parameter, because…

2. …overloading (of functions as well as operators) only allows resolution on the _parameters_, not the _return type._ Template functions are by definition overloads, even if there’s only one of them.

See the C++ Standard, section 13, for details if you want it. The justification for this isn’t given explicitly, but I suspect that it’s for when you cast a function result:

int x = (int)function\_with\_overloads();

…how would you know which one to call?

Incidentally, there’s an increasing movement to use “typename” rather than “class” for template specifications, since class is overloaded to mean something else. The two are interchangeable, so:

template \<class T\> foobar(T& barfoo);

and

template \<typename T\> foobar(T& barfoo);

are the same declaration, except the second one’s more explicit, always a plus in C++.

---

<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:** [September 28, 2005, 8:14pm UTC](https://boards.straightdope.com/t/c-question-templates/323888/5 "2005-09-28T20:14:03Z")

</div>

> [@Trunk](#):
>
> I don’t actually have access to the templated class (in this case, Trunk).
> 
> I mean, I have the source code and all, but it’s third party. I’m adding functions that operate on the classes, but i"m not actually adding anything to the classes.

… How about deriving from the third-party classes?

```auto

template<class T> class Trunk {
  // ...
};

template<class T> class MyTrunk : public Trunk<T> {
public:
  void operator~( ) { /* ... */ }
};

```

---

<div class="post-metadata">

**Author:** ![SomeGuy](https://avatars.discourse-cdn.com/v4/letter/s/ac8455/32.png) [@SomeGuy](https://boards.straightdope.com/u/SomeGuy)\
**Post date:** [September 29, 2005, 12:46am UTC](https://boards.straightdope.com/t/c-question-templates/323888/6 "2005-09-29T00:46:49Z")

</div>

Can you call your template function like this:

```auto

int main()
{
   Trunk<double> d; 
   d = f<double>();
}

```

?

---

<div class="post-metadata">

**Author:** ![Trunk](https://avatars.discourse-cdn.com/v4/letter/t/87869e/32.png) [@Trunk](https://boards.straightdope.com/u/Trunk)\
**Post date:** [September 29, 2005, 11:30am UTC](https://boards.straightdope.com/t/c-question-templates/323888/7 "2005-09-29T11:30:17Z")

</div>

Thanks.

**TimeWinder** , your (2) is pretty much what I thought. (I used to live in Corvallis, btw)

**Ompha** , I could try that but at that point, its getting more convoluted than my original work-around.

**SomeGuy** , that was actually something I tried, but no dice.

---

<div class="post-metadata">

**Author:** ![Ponder\_Stibbons](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/ponder_stibbons/32/343_2.png) [@Ponder\_Stibbons](https://boards.straightdope.com/u/Ponder_Stibbons)\
**Post date:** [September 29, 2005, 11:37am UTC](https://boards.straightdope.com/t/c-question-templates/323888/8 "2005-09-29T11:37:20Z")

</div>

> [@Trunk](#):
>
> **Ompha** , I could try that but at that point, its getting more convoluted than my original work-around.

Really? I find **Ompha** ’s solution of deriving from the base to be a lot clearer to follow than your workaround. Of course, that’s just MHO, no offense. 🙂

---

<div class="post-metadata">

**Author:** ![Trunk](https://avatars.discourse-cdn.com/v4/letter/t/87869e/32.png) [@Trunk](https://boards.straightdope.com/u/Trunk)\
**Post date:** [September 29, 2005, 11:52am UTC](https://boards.straightdope.com/t/c-question-templates/323888/9 "2005-09-29T11:52:16Z")

</div>

For completeness, this also works. . .

Actual function I desire that doesn’t work:

```auto

template <class T>
Trunk<T> f(long l)
{
   Trunk<T> t;
   //something
   return t;
}

```

function that works:

```auto

template <class T>
Trunk<T> f(Trunk<T>& dummy, long l)
{
   Trunk<T> t;
   //something that does NOTHING to dummy
   return t;
}

```

Which might look overloaded by return type (and a similar function was actually the original source of my confusion) but is really just plain-old vanilla overloaded by parameter type.

And, as we desire, the compiler pukes if I try to do something like this. . .

```auto

int main() 
{
Trunk<long> t;
Trunk<double> t2;

t2 = f(t, 3);
}

```

Makes sense to me, now.

---

<div class="post-metadata">

**Author:** ![SomeGuy](https://avatars.discourse-cdn.com/v4/letter/s/ac8455/32.png) [@SomeGuy](https://boards.straightdope.com/u/SomeGuy)\
**Post date:** [September 29, 2005, 12:00pm UTC](https://boards.straightdope.com/t/c-question-templates/323888/10 "2005-09-29T12:00:30Z")

</div>

> [@Trunk](#):
>
> **SomeGuy** , that was actually something I tried, but no dice.

I’m confused then. What complaint does your compiler issue when you do that?

---

<div class="post-metadata">

**Author:** ![Trunk](https://avatars.discourse-cdn.com/v4/letter/t/87869e/32.png) [@Trunk](https://boards.straightdope.com/u/Trunk)\
**Post date:** [September 29, 2005, 12:09pm UTC](https://boards.straightdope.com/t/c-question-templates/323888/11 "2005-09-29T12:09:16Z")

</div>

> [@SomeGuy](#):
>
> I’m confused then. What complaint does your compiler issue when you do that?

I’m sorry. That did work.

I might have forgot to save the header file.

(I’m building a library in one project, and then adding that library to another bit of code that I’m using to test the library. Problem is, in Borland, it will do the library build using your alterations without resaving the altered header file. You need to save that explicitly.)

---

<div class="post-metadata">

**Author:** ![SomeGuy](https://avatars.discourse-cdn.com/v4/letter/s/ac8455/32.png) [@SomeGuy](https://boards.straightdope.com/u/SomeGuy)\
**Post date:** [September 29, 2005, 12:21pm UTC](https://boards.straightdope.com/t/c-question-templates/323888/12 "2005-09-29T12:21:51Z")

</div>

> [@Trunk](#):
>
> That did work.

I think that’s the right way to go then (the way you’re “supposed” to do it).

---

<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:** [September 29, 2005, 2:21pm UTC](https://boards.straightdope.com/t/c-question-templates/323888/13 "2005-09-29T14:21:21Z")

</div>

> [@Trunk](#):
>
> function that works:
> 
> ```auto
> 
> template <class T>
> Trunk<T> f(Trunk<T>& dummy, long l)
> {
> Trunk<T> t;
> //something that does NOTHING to dummy
> return t;
> }
> 
> ```
> 
> Which might look overloaded by return type (and a similar function was actually the original source of my confusion) but is really just plain-old vanilla overloaded by parameter type.

You have a paragraph of comments around that one, right?

---

<div class="post-metadata">

**Author:** ![Trunk](https://avatars.discourse-cdn.com/v4/letter/t/87869e/32.png) [@Trunk](https://boards.straightdope.com/u/Trunk)\
**Post date:** [September 29, 2005, 5:44pm UTC](https://boards.straightdope.com/t/c-question-templates/323888/14 "2005-09-29T17:44:37Z")

</div>

> [@ultrafilter](#):
>
> You have a paragraph of comments around that one, right?

I wouldn’t actually do that in code I expected anyone else from now to eternity to see.

I talked to a guy today with some experience with this. He also said that calling

```auto

f<T>(); 

```

is the way to go.

I just was a little blinded because I was stripping down an original function that was defined with the return type in the parameter list and I got problems when I wanted to take it out.

I envisioned code like

```auto

Trunk<double> dT = f(5);
Trunk<int> iT = f(5);

```

which I think we’d all be fine with if it stopped there. But the real ambiguity problems arise when you have

```auto

g(Trunk<int>) { /* do something */ }
g(Trunk<double>) {/* do something */}

```

And someone just goes and calls

```auto

g(f(5));

```

Which is just the basic argument against overloading by return type. I just blew right past it though.
