// 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;
}
Template function specialization (MS C++ 2005 Express)
Hi,
I'm having problems trying to write a specialized version of a template function.
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?
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
[edit] As an example for your header:
jfl.
#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.
You will have to hint the compiler about inlining these functions,
e.g.
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;}
@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.
@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.
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.
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.
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
@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
@Nitage Thanks, I shall try that next.
P.S. Yup that works! Can't say I understand WHY, tho .... =\
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 .... =\
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement