Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 浮点和双字面值模板类中的函数专门化_C++_Function_Templates_Literals_Specialization - Fatal编程技术网

C++ 浮点和双字面值模板类中的函数专门化

C++ 浮点和双字面值模板类中的函数专门化,c++,function,templates,literals,specialization,C++,Function,Templates,Literals,Specialization,我试图找到一个解决方案,在模板类方法中包含常量数字文本。我正在制作一些数学模板类,用于float或double类型。问题在于,根据数据类型不同,文本是不同的(例如,“0.5f”表示浮点,而“0.5”表示双精度)。到目前为止,我提出了两个解决方案。第一个的一些假设代码: 模板 上课 { 公众: T剂量测定法(tx); }; 模板 float SomeClass::doSomething(float x) { 浮动y=0.5f; /* *做计算。。。 */ 返回x; } 模板 double Some

我试图找到一个解决方案,在模板类方法中包含常量数字文本。我正在制作一些数学模板类,用于float或double类型。问题在于,根据数据类型不同,文本是不同的(例如,“0.5f”表示浮点,而“0.5”表示双精度)。到目前为止,我提出了两个解决方案。第一个的一些假设代码:

模板
上课
{
公众:
T剂量测定法(tx);
};
模板
float SomeClass::doSomething(float x)
{
浮动y=0.5f;
/*
*做计算。。。
*/
返回x;
}
模板
double SomeClass::doSomething(双x)
{
双y=0.5;
/*
*做计算。。。
*/
返回x;
}
上面的方法强制重写它所使用的每种类型的整个方法

另一种方法:

模板
上课
{
公众:
T剂量测定法(tx);
私人:
T getValue();
};
模板
T SomeClass::doSomething(tx)
{
T y=getValue();
/*
*做计算。。。
*/
返回x;
}
模板
float SomeClass::getValue()
{
返回0.5f;
}
模板
double SomeClass::getValue()
{
返回0.5;
}
这个方法不需要为特定类型多次编写相同的方法,但需要为方法中需要使用的每个“幻数”都提供许多getValue()方法


有没有另一种“更优雅”的方法来解决这个问题?

您不必担心这个问题-使用0.5,如果类型是float,编译器仍然会将其初始化为与使用0.5f时相同的最佳值

这有点冗长,但您可能想在这里通读我答案中的“支持多态性的其他机制”部分:


要在整个函数中更广泛地使用浮点常量,尤其是在比较和表达式中,请阅读下面提到的链接bluemess…

假设实际上需要在两个专门化中使用不同的值(例如,0.5和0.5f不需要)这将大大减少打字工作量:

template <typename T>
class SomeClass
{
  public:
    T doSomething(T x);

  private:
    static const T magic_number_1;
};

template <typename T>
T SomeClass<T>::doSomething(T x)
{
  T y = magic_number_1;
  /* 
   * Do computations...
  */
  return x;
}

template <>
const float SomeClass<float>::magic_number_1 = 0.5f;

template <>
const double SomeClass<double>::magic_number_1 = 0.5;
模板
上课
{
公众:
T剂量测定法(tx);
私人:
静态常数幻数1;
};
模板
T SomeClass::doSomething(tx)
{
T y=幻数1;
/* 
*做计算。。。
*/
返回x;
}
模板
常量float SomeClass::magic_number_1=0.5f;
模板
常数double SomeClass::magic_number_1=0.5;

谢谢大家的回答和评论。我允许自己总结一下到目前为止所说的话,并补充我的结论

我将实现一些数学类模板,将其实例化以与float或double类型一起使用。需要在类内部使用一些数字文本。它们将是一些常用的数值文本和常量,如0.0、0.5、1.0、pi等。我正在寻找一种解决方案,使类实例化根据其类型在不同的文本上工作

是否使用浮点和双字面值?

关于是否需要为float和double使用单独的文本这个话题,讨论稍微深入了一点。这可能是因为我在问题中给出了一个不幸的例子。在本例中,文本将在编译时转换为正确的类型,因此不会造成任何伤害。但通常情况下,在表达式中需要使用文字,例如:

float foo(float x)
{
返回x*3.14;
}
这将迫使编译器将x转换为double,进行计算,然后将结果转换回float。这种行为的利弊:

优点:

  • 精度提高,因为实际计算将以双倍速度进行 精确性
缺点:

  • 如果性能是一个问题,这可能会导致更快和更高的速度 执行速度较慢,具体取决于环境和平台。这 根据实现引入一些性能更改,这 就我所知,很糟糕
  • 引入计算不一致性,因为某些操作将 根据文字使用情况,在浮点上完成,有些在双精度上完成。这 可能还会打开一些bug暴露
  • 它打破了一开始将浮动类专门化的想法 因为不管怎样,内部计算都是在双精度上进行的
总之,目标是使类实例化在适当的类型上工作,而不需要任何额外的转换。在任何地方使用双类型文本(如0.5)并将适当的转换留给编译器的想法都不是一个选项

有关该主题的更多信息:

可能的解决方案?

  • 为每个模板实例化类型专门化方法,其中 必须使用文本。这可能是最糟糕的解决方案,因为它 强制编写同一代码两次,对 文字
  • 使专用的
    getValue()
    方法或作为专用的 成员。这可能会导致出现一些愚蠢的命名成员或方法 在类中,例如
    getZeroPointFive()
  • Mohammad和Tony Delroy指出,用
    static\u cast()
    就可以了。转换为正确的类型将 必须在编译时完成

如果只是关于文字,我想您可以使用casting static\u cast()我在问题中没有提到,但我希望避免任何转换,无论是显式转换还是隐式转换。假设我将使用“0.5”文字。这不会导致隐式(运行时?)转换在某个点上浮动吗?在我给出的示例中,它可能并不重要,但通常我宁愿避免转换。它将是编译时转换。我发现使用“0.5”在某些情况下,float的literal将导致多次转换,此处对此进行了解释:@bluemass:对于问题中所示的赋值,您可以期望它在编译时完成。。。(当然,GCC 4.5.3会这样做