C++ 模板函数专业化?

C++ Template function specializations?

我正在尝试制作一组​​非常简单的 float/double 比较函数,用于将值与指定的小数位进行比较。

#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)" (??$floatCompare@M@lqpro@@YA_NMMH@Z) referenced in function "public: void __thiscall lqpro_tests::FloatCompare_tests::ComparingFloatsZeroToOneReturnsFalse(void)" (?ComparingFloatsZeroToOneReturnsFalse@FloatCompare_tests@lqpro_tests@@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,一次用于 double,但我不想重复代码...

我做错了什么?

谢谢

您似乎在尝试比较某个指定精度内的数字,即与 epsilon 进行比较。这是我用来执行此操作的函数:

#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";
    }
}

以下声明 专业化(您没有定义

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);

但是由于所有用法都可以访问定义,您甚至可以完全省略这些行。