我正在尝试制作一组​​非常简单的浮点/双精度比较函数,这些函数会将值比较到指定的小数位。

#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一次,但是我不想重复代码。

我究竟做错了什么?

谢谢

#1楼 票数: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);

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

#2楼 票数:0

看来您正在尝试以指定的精度比较数字,即与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";
    }
}

  ask by jump translate from so

未解决问题?本站智能推荐:

3回复

澄清模板功能专业化

我想创建一个计算器 现在我想让这个Caculator添加字符串,所以add(“Tim”,“Joe”)会给我“TimJoe”。 我是否可以通过对现有类进行必要的更改来使用模板函数专门化来实现此目的。
3回复

模板专业化类功能

因此,我有一个用作数据结构的类,但是我希望如果该类存储指针,则该类中的一个函数的行为会有所不同。 我想做的是,而不是返回指针,而是希望它在调用[]运算符时返回对该对象的引用。 这是之前的课程 我想添加这个或类似的东西。 该代码在类之外 但是运行代码时出现此错误 从我阅读的内容
4回复

隐藏功能模板,声明专业化

这是C ++模板的后续内容:防止实例化基本模板 我使用模板来实现函数重载,而不会造成隐式类型转换的麻烦: 声明函数模板,定义所需的专业化(重载)。 一切正常,除非错误的代码在链接阶段之前不会产生错误: lib.hpp: lib.cpp: main.cpp中: gcc输出:
1回复

功能模板专业化格式

以下函数模板中第二个括号<>的原因是什么: 这出现在SO问题中,有人建议在operator()之后缺少括号,但是我找不到解释。 如果它是表单的类型特化(完全特化),我理解其含义: 但是对于功能模板: 这适合这种情况?: 示例代码似乎有效并且没有给出任何警告/错误(
1回复

VS2017模板特化错误无法从'Class*(__cdecl*)(Args...)'转换为'Class*(__cdecl*)(Args...)'

这是我迁移到VS2017的代码库的简单版本。 以下代码在VS2013和英特尔C ++编译器2017更新4中编译,但在VS2013中不编译。 我在Constructor类的定义上收到错误: main.cpp(20):错误C2440:'specialization':无法从'Class
1回复

浮点的C++模板专业化

我想专门针对浮点类型的X类方法。 以下代码可以编译并完美运行: x.hpp: x.cpp: 现在,类似于此答案,我将cpp文件更改为: 不幸的是,这导致以下编译器错误: 有人可以向我解释我所缺少的吗? 提前致谢! 编辑 :我们显式实例化cpp文件末尾的模板类,以便我
1回复

C++模板专业化问题

我在C ++中遇到了专门的函数模板问题。 我正在编写一个比较函数模板,用于排序不同的数据类型。 这是我的代码的一部分: 所以我可以按值和尖头值排序。 但是,当我尝试将此函数传递给sort : 我收到编译错误: 为什么? 我明确提供了模板类型! 作为参考,我的排序函数模板如
2回复

关于模板专业化

我需要为哈希表提供一个插入/查找/删除接口。 我编写哈希表只是为了提供内部存储区/条目管理。 哈希函数应从外部提供。 我现在停留在如何公开接口上,以便哈希表可以处理字节数组以及固定长度的数据类型。 问题在于,对于字节数组,散列函数需要知道数组的长度,而对于其他类型,散列函数可以不使用该信