Jump to content
  • Advertisement
Sign in to follow this  
Red Ant

Template function specialization (MS C++ 2005 Express)

This topic is 4861 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm having problems trying to write a specialized version of a template function.
// In MathFunctions.h ...
#include <limits>

namespace MathFunctions
{
    /// @brief Template function to test if two values of the same type are equal.
    template < class T > bool testEquality( T valueOne, T valueTwo );

    /// @brief Specialization for doubles.
    template <> bool testEquality( double flValueOne, double flValueTwo );
}

template < class T > bool MathFunctions::testEquality( T valueOne, T valueTwo )
{
    // Normal comparison.
    return valueOne == valueTwo;
}

template <> bool MathFunctions::testEquality( double flValueOne, double flValueTwo )
{
    // Special treatment for floating point values.
    const double flDiff = fabs( flValueOne - flValueTwo );

    if ( flDiff < std::numeric_limits< double >::epsilon() )
    {
        return true;
    }

    return false;
}


The linker throws the following error: main.obj : error LNK2005: "bool __cdecl MathFunctions::testEquality<double>(double,double)" (??$testEquality@O@MathFunctions@@YA_NOO@Z) already defined in MathFunctions.obj ... and I'm clueless what to do about it. I'll admit that template programming is not exactly one of my strengths. =\ Anyhow, does anyone know what I'm doing wrong?

Share this post


Link to post
Share on other sites
Advertisement
You are missing inclusion guards. Since you are using MSVC, you can add #pragma once to the top of your .h file, or you can use the portable
#ifndef UNIQUENAMEHERE
#ifndef SAMEUNIQUENAMEHERE

// Code goes here

#endif

[edit] As an example for your header:
#ifndef MATHFUNCTIONS_H
#define MATHFUNCTIONS_H

#include <limits>

namespace MathFunctions
{
/// @brief Template function to test if two values of the same type are equal.
template < class T > bool testEquality( T valueOne, T valueTwo );

/// @brief Specialization for doubles.
template <> bool testEquality( double flValueOne, double flValueTwo );
}

template < class T > bool MathFunctions::testEquality( T valueOne, T valueTwo )
{
// Normal comparison.
return valueOne == valueTwo;
}

template <> bool MathFunctions::testEquality( double flValueOne, double flValueTwo )
{
// Special treatment for floating point values.
const double flDiff = fabs( flValueOne - flValueTwo );

if ( flDiff < std::numeric_limits< double >::epsilon() )
{
return true;
}

return false;
}

#endif



jfl.

Share this post


Link to post
Share on other sites
You will have to hint the compiler about inlining these functions,
e.g.

template < class T > inline bool MathFunctions::testEquality( T valueOne, T valueTwo )
{
// Normal comparison.
return valueOne == valueTwo;
}

template <> inline bool MathFunctions::testEquality( double flValueOne, double flValueTwo )
{
// Special treatment for floating point values.
const double flDiff = fabs( flValueOne - flValueTwo );

if ( flDiff < std::numeric_limits< double >::epsilon() )
{
return true;
}

return false;
}


Share this post


Link to post
Share on other sites
@jflanglois Nah, I got the inclusion guards in there alright. Sorry, I didn't post the whole file ... just that parts I deemed relevant.

@darookie Seriously?? Why's that? ... I mean I've used templates before, and I've never had anyone tell me template functions have to be inline to work. I'm not saying you're wrong, but it does seem strange to me.

Share this post


Link to post
Share on other sites
The template version doesn't have to be inlined.

The specialised version has to be inlined (or have it's definition placed in a source file) because there's no type substitution going on in the specialised version.

The inline keyword is being used here to tell the compiler about the linkage of the specialised function.

Share this post


Link to post
Share on other sites
template <> bool testEquality< double >( double flValueOne, double flValueTwo )
Both for the declaration and the definition, to tell the compiler what you're specializing on. (EDIT: well, maybe. According to the final draft standard it's legal not to specify trailing template arguments if they can be deduced from the argument types, but GCC 3.3.1 for one doesn't like doing so, at least not for this example).

Enigma

Share this post


Link to post
Share on other sites
@Enigma Thanks, but the linker still keeps moaning. :( As for the standard, yeah I saw Stroustrup specialize a function in exactly the same way as I did


template <class T> bool less( T a, T b ) { return a < b; }
template <> bool less( const char* a, const char* b ) { return strcmp( a, b ) < 0; }





@Nitage Thanks, I shall try that next.

P.S. Yup that works! Can't say I understand WHY, tho .... =\

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!