For Programmers: Free Programming Magazines  


Home > Archive > VC Language > May 2006 > Tricky template problem









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Tricky template problem
Murrgon

2006-05-31, 7:15 pm

I have a simple template function I wrote that looks like this:

template<typename INTTYPE> INTTYPE T_IntPower(INTTYPE nBase, INTTYPE nExp)
{
return 0 < nExp ? nBase * IntPower(nBase, nExp - 1) : 1);
}

Now let's say I dont' want anyone to call this function using floating
point types, as that is not how it was intended. I was under the
impression I could add something like this:

template<> float T_IntPower<float>(float nBase);

.... where the specialization is declared, but the body of the function
is not provided. This would generated a complier error if anyone ever
attempted to call the function using floats.

The problem is this doesn't work. I get the error C2912: explicit
specialization; 'float T_IntPower<float>(float)' is not a specialization
of a function template. So either I am wrong about being able to do
what I want, or I somehow have the syntax wrong.

I am using VC7.1 (2003)

Thank you
Abdo Haji-Ali

2006-05-31, 7:15 pm

"Murrgon" <murrgon@hotmail.com> wrote in message
news:OWpxJHMhGHA.1324@TK2MSFTNGP04.phx.gbl...
> I have a simple template function I wrote that looks like this:
>
> template<typename INTTYPE> INTTYPE T_IntPower(INTTYPE nBase, INTTYPE nExp)
> {
> return 0 < nExp ? nBase * IntPower(nBase, nExp - 1) : 1);
> }
>
> Now let's say I dont' want anyone to call this function using floating
> point types, as that is not how it was intended. I was under the
> impression I could add something like this:
>
> template<> float T_IntPower<float>(float nBase);


Almost, just write:
float T_IntPower(float nBase);

This way the compiler will try to call this function with float types
instead of the "templated" one.
However, the caller may always do something like this:
T_IntPower<float>(...);
Which would call the templated function anyway...

> ... where the specialization is declared, but the body of the function
> is not provided. This would generated a complier error if anyone ever
> attempted to call the function using floats.

A linker error, not a compiler one

BTW, you might consider throwing an exception instead of leaving the
function without implementation

--
Abdo Haji-Ali
Programmer
In|Framez


Igor Tandetnik

2006-05-31, 7:15 pm

Murrgon <murrgon@hotmail.com> wrote:
> I have a simple template function I wrote that looks like this:
>
> template<typename INTTYPE> INTTYPE T_IntPower(INTTYPE nBase, INTTYPE
> nExp) {
> return 0 < nExp ? nBase * IntPower(nBase, nExp - 1) : 1);
> }
>
> Now let's say I dont' want anyone to call this function using floating
> point types, as that is not how it was intended. I was under the
> impression I could add something like this:
>
> template<> float T_IntPower<float>(float nBase);
>
> ... where the specialization is declared, but the body of the function
> is not provided.


It's not a valid specialization since the signature does not match. The
general template has two parameters while your purported specialization
only has one.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


Carl Daniel [VC++ MVP]

2006-05-31, 7:15 pm

Abdo Haji-Ali wrote:
> BTW, you might consider throwing an exception instead of leaving the
> function without implementation


IMO that would be a worse choice. Leaving the function unimplemented
guarantees a build-time error (linker, in this case), while throwing an
exception changes it to a runtime error. If the function should truly never
be called, the build-time error is preferable.

-cd




Ulrich Eckhardt

2006-05-31, 7:15 pm

Murrgon wrote:
> I have a simple template function I wrote that looks like this:
>
> template<typename INTTYPE> INTTYPE T_IntPower(INTTYPE nBase, INTTYPE nExp)
> {
> return 0 < nExp ? nBase * IntPower(nBase, nExp - 1) : 1);
> }

[..]
> template<> float T_IntPower<float>(float nBase);
>
> ... where the specialization is declared, but the body of the function
> is not provided. This would generated a complier error if anyone ever
> attempted to call the function using floats.


Wrong, it would cause a linker error.

> The problem is this doesn't work. I get the error C2912: explicit
> specialization; 'float T_IntPower<float>(float)' is not a specialization
> of a function template.


Right, as there is a function template with the same name but one that takes
two(!) parameters.

Other than that, there are metaprogramming techniques that could allow you
to detect if the template argument is an integral type and then either
invoke the right implementation or generate an error. Just search
for 'template metaprogramming'.

Uli

Abdo Haji-Ali

2006-05-31, 7:15 pm

"Carl Daniel [VC++ MVP]" <cpdaniel_remove_this_and_nospam@mvps.org.nospam>
wrote in message news:O7NG7UMhGHA.1320@TK2MSFTNGP04.phx.gbl...
> Abdo Haji-Ali wrote:
>
> IMO that would be a worse choice. Leaving the function unimplemented
> guarantees a build-time error (linker, in this case), while throwing an
> exception changes it to a runtime error. If the function should truly

never
> be called, the build-time error is preferable.
>
> -cd

Good point, agreed...
--
Abdo Haji-Ali
Programmer
In|Framez


Murrgon

2006-05-31, 7:15 pm

Igor Tandetnik wrote:
> Murrgon <murrgon@hotmail.com> wrote:
>
> It's not a valid specialization since the signature does not match. The
> general template has two parameters while your purported specialization
> only has one.


Ahhh! You're right. Thanks a tonne!
Andre Kaufmann

2006-05-31, 7:15 pm

Murrgon wrote:
> I have a simple template function I wrote that looks like this:
>
> template<typename INTTYPE> INTTYPE T_IntPower(INTTYPE nBase, INTTYPE nExp)
> {
> return 0 < nExp ? nBase * IntPower(nBase, nExp - 1) : 1);
> }
>
> Now let's say I dont' want anyone to call this function using floating
> point types, as that is not how it was intended. I was under the
> impression I could add something like this:
>
> [...]


You could use the static assertion macro from boost.

http://www.boost.org/doc/html/boost_staticassert.html

Which allows you to generate a specified compile time error.


Andre
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com