0

我想做一個非常簡單的浮點/雙比較函數集,它將比較值到指定的小數點位置。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 ========== 

我想我可以只寫floatCompare()函數兩次,一次爲float和一次雙,但我不希望重複的代碼。 ..

我在做什麼錯?

感謝

+0

如果參數不是float,則可以使用std :: enable_if停止模板的編譯。將以下內容作爲模板參數添加到myAbs中:「typename = typename std :: enable_if :: value> :: type」。它在type_traits中。 – Robinson

+0

是否有任何特別的理由拋出異常「調用非浮點型參數」,而不是獲取編譯時錯誤,試圖調用未知超載?是否有任何特殊的原因使用功能專業化而不是重載?最後,如果刪除不必要的未定義的特化,「floatCompare」的工作方式就像你想的那樣。 – WindyFields

+0

按myAbs(左 - 右)'你的意思是'myAbs(左,右)' – WindyFields

回答

1

以下聲明特(你不要定義

template<> 
bool floatCompare<>(float left, float right, const int decimals); 

template<> 
bool floatCompare<>(double left, double right, const int decimals); 

如果你想明確地實例化它們,它會是

template 
bool floatCompare<float>(float left, float right, const int decimals); 

template 
bool floatCompare<double>(double left, double right, const int decimals); 

但所有使用訪問定義,你甚至可以完全忽略茨艾倫e行。

+0

我在想,我必須專門化,否則我必須通過我的代碼浮動比較(...)。謝謝 – jump

0

它看起來像你想一些指定的精度範圍內比較數字,即有小量比較。這是我用做它的函數:

#include <iostream>  
#include <cmath> 

template <typename T0, 
      std::enable_if_t<std::is_floating_point<T0>::value>* = nullptr> 
bool Equal(T0 a, T0 b, T0 epsilon) 
{  
    return std::abs(a - b) <= epsilon; 
} 

int main() 
{ 
    if (Equal(0.1, 0.15, 0.1)) 
    { 
     std::cout << "They are equal to within 0.1";  
    } 
    else 
    { 
     std::cout << "They are not equal to within 0.1"; 
    } 
}