简体   繁体   English

C ++模板功能专业化?

[英]C++ Template function specializations?

I'm trying to make a very simple set of float/double comparison functions that will compare values out to a specified decimal position. 我正在尝试制作一组​​非常简单的浮点/双精度比较函数,这些函数会将值比较到指定的小数位。

#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...

My problem is that this won't compile for me. 我的问题是,这不会为我编译。 When trying, it get the following error... 尝试时,出现以下错误...

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 ==========

I suppose that I could just write the floatCompare() function twice, once for float and once for double but I'd prefer not to duplicate the code... 我想我可以只写一次floatCompare()函数两次,一次是float一次,一次是double一次,但是我不想重复代码。

What am I doing wrong? 我究竟做错了什么?

Thanks 谢谢

The following declares specializations (that you don't define ) 以下声明专业化(您未定义

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

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

If you want to instantiate them explicitly, it would be 如果要显式实例化它们,那将是

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

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

but as all usage has access to definition, you can even omit completely those lines. 但是由于所有用法都可以使用定义,因此您甚至可以完全省略这些行。

It looks like you're trying to compare numbers within some specified precision, ie compare with epsilon. 看来您正在尝试以指定的精度比较数字,即与epsilon比较。 This is the function I use to do it: 这是我用来做的功能:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM