私は、値を指定された小数点位置と比較する非常に単純なfloat/double比較関数のセットを作ろうとしています。C++テンプレート関数の特殊化?
#include "stdafx.h"
#include "CppUnitTest.h"
#include <exception>
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace lqpro
{
namespace /* anonymous */
{
template<typename _type>
_type myAbs(_type left, _type right)
{
throw std::exception("lqpro::myAbs() called with non-float type parameter");
}
template<>
double myAbs(double left, double right)
{
return fabs(left - right);
}
template<>
float myAbs(float left, float right)
{
return fabsf(left - right);
}
template<typename _type>
static _type quick_pow10(int n)
{
static _type pow10[10] = {
1.0, 10.0, 100.0, 1000.0, 10000.0,
100000.0, 1000000.0, 10000000.0,
100000000.0, 1000000000.0
};
return pow10[n];
}
} // anonymous...
template<typename _type>
bool floatCompare(_type left, _type right, const int decimals=5)
{
_type _mul = quick_pow10<_type>(decimals);
_type _left = left * _mul;
_type _right = right * _mul;
_type _diff = myAbs(left - right);
if (static_cast<int>(_diff) == 0)
return true;
return false;
}
template<>
bool floatCompare<>(float left, float right, const int decimals);
template<>
bool floatCompare<>(double left, double right, const int decimals);
} // lqpro...
namespace lqpro_tests
{
TEST_CLASS(FloatCompare_tests)
{
public:
TEST_METHOD(ComparingFloatsZeroToOneReturnsFalse)
{
Assert::IsFalse(lqpro::floatCompare(0.0f, 1.0f, 5));
}
};
} // lqpro_tests...
私の問題は、これは私のためにコンパイルされないということです。しようとすると、それは次のエラーを取得する...
1>FloatCompare_tests.cpp
1> Creating library D:\proj\LottoQuestPro\LottoQuestPro_Solution\Debug\LQPro_tests.lib and object D:\proj\LottoQuestPro\LottoQuestPro_Solution\Debug\LQPro_tests.exp
1>FloatCompare_tests.obj : error LNK2019: unresolved external symbol "bool __cdecl lqpro::floatCompare<float>(float,float,int)" ([email protected]@[email protected]@[email protected]) referenced in function "public: void __thiscall lqpro_tests::FloatCompare_tests::ComparingFloatsZeroToOneReturnsFalse(void)" ([email protected][email protected][email protected]@QAEXXZ)
1>D:\proj\LottoQuestPro\LottoQuestPro_Solution\Debug\LQPro_tests.dll : fatal error LNK1120: 1 unresolved externals
1>Done building project "LQPro_tests.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
は、私はちょうど、二重に一度フロート用と1回、2回floatCompare()関数を書くことができますが、私は、コードを複製しないことを好むだろうと仮定します。 ..
私は間違っていますか?
おかげ
パラメータが浮動しない場合、std :: enable_ifを使用してテンプレートのコンパイルを停止することができます。 myAbsにテンプレートパラメータとして次を追加します。 "typename = typename std :: enable_if :: value> :: type"それはtype_traitsにあります。 –
Robinson
存在しないオーバーロードを呼び出すときにコンパイル時エラーが発生するのではなく、「非float型パラメータで呼び出された」例外をスローする特別な理由はありますか?オーバーロードの代わりに関数の特殊化を使用する特別な理由はありますか?そして最後に、 'floatCompare'は、不要な未定義の特殊化を取り除いた場合と同じように機能します。 – WindyFields
'myAbs(左 - 右)'はあなたが 'myAbs(左、右)'を意味しました – WindyFields