Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.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++_Templates_C++11_Type Conversion_Literals - Fatal编程技术网

C++ 表达模板化数值文字的最佳方式是什么?

C++ 表达模板化数值文字的最佳方式是什么?,c++,templates,c++11,type-conversion,literals,C++,Templates,C++11,Type Conversion,Literals,我有一个函数,可以简化成这样: template<class T> T foo(T x) { return 123.45 / x; } 模板 T foo(T x) { 返回123.45/x; } 我想确保数字文字123.45与x的类型相同。假设T可以是任何数字类型:有符号/无符号字符到long long或float到long double 用什么最现代的方式表明123.45应为T型 我的要求 不应发出任何警告(打开每个警告) 我希望十进制数123.45在计算中使用时具有T的

我有一个函数,可以简化成这样:

template<class T>
T foo(T x)
{
  return 123.45 / x;
}
模板
T foo(T x)
{
返回123.45/x;
}
我想确保数字文字123.45与x的类型相同。假设T可以是任何数字类型:有符号/无符号字符到long long或float到long double


用什么最现代的方式表明123.45应为T型

我的要求

  • 不应发出任何警告(打开每个警告)
  • 我希望十进制数123.45在计算中使用时具有T的精度
  • 我想要实现这些目标的最优雅的解决方案
审议中的问题

  • “旧式CAST”,即<代码>(t)123.45 < /C>基本上是用C++来表示的。
  • static\u cast(123.45)
    似乎是正确的类型。然而,它是冗长的,我从来没有见过在文字上使用它
  • 我不确定在T为长双精度的情况下,是否需要后缀(例如,
    123.45L
    )来获得最大精度,或者编译器是否会自动使用精度最高的十进制到二进制转换
更新日期5-7-2014


在将代码库中的数百个强制转换更改为
T(123.45)
形式后,我发现有时这种语法不可用。例如,您不能做<代码> long double(123.45)< /COD>,因为C++不支持多令牌类型的构造函数。在这些情况下,我选择了
static\u cast(123.45)

static\u cast
是一种选择。这就是C类型转换所等价的,在任何保留原始含义但改变值类型的转换中

如果是具有数字特征的类类型,
static\u cast
将调用一个单参数构造函数,甚至是一个
explicit
one


如果要避免缩小转换范围,可以使用语法
T{123.45}
。这不像C样式转换,而是使用直接列表初始化。它仍然允许显式构造函数,但对其参数类型的任何数字转换都必须精确。(不允许溢出或舍入。对于文本,此约束针对特定值进行检查,而不是作为类型之间的关系。但是,当我将
12.0
传递给
int
时,GCC会发出警告;我不确定这是否正确。)

静态强制转换是自然的。如果你还没有看到它,那么,并不是每个人都能看到发生的一切:-)我倾向于使用C风格的类型转换,当(a)我知道这两种类型时,(b)我有权有点懒惰。正如您将在下面的代码中看到的

如果希望在
T
double
更精确时获得精度,则确实需要
L
后缀。潜在
static_cast(123.45)!=123.45升

假设
T
是某种更精确的类型,比如GMP中的
mpf\u类
,或者是
long double
之外的某种特定于编译器的扩展类型。您可能需要考虑<代码> Boo::ListalyCost(“123.45”)< /代码>。当然,这对整数类型不起作用,您需要两个单独的案例,分别使用
enable\u if
或其他什么

还要注意,如果
T
是一个比
int
低秩的整数类型,那么例如
short(123.45)/x
int(123.45)/x
相同,因为除法是以
int
任何方式执行的,并且
short(123.45)=int(123.45)
。如果
T
是一个比
int
秩更高的整数类型,那么例如
long(123.45)/x
仍然与
int(123.45)/x
相同,因为将以
T
类型和
int(123.45)=long(123.45)
执行除法。此分析依赖于以下事实:
123
在任何整数类型[*]中具有相同的值。如果您可以将
123.45
概括为
T
,那么情况可能会有所不同。例如
-1/(无符号字符)2!=(无符号字符)-1/(无符号字符)2


[*]我忽略了
bool
,实际上我不记得它是否是数字类型。

您也可以尝试以下方法:

// RealConstant.h

template <typename Real>
class RealConstant
{
public:

    static 
    const Real value;

};

#define REAL_CONSTANT_DECLARATION(Real) \
template <> \
const Real RealConstant<Real>::value;

REAL_CONSTANT_DECLARATION(float)
REAL_CONSTANT_DECLARATION(double)
REAL_CONSTANT_DECLARATION(long double)

#undef REAL_CONSTANT_DECLARATION


// RealConstant.cpp

#include "RealConstant.h"

#define REAL_CONSTANT_DEFINITION(Real, constantValue) \
template <> \
const Real RealConstant<Real>::value = constantValue;

REAL_CONSTANT_DEFINITION(float, 123.45f)
REAL_CONSTANT_DEFINITION(double, 123.45)
REAL_CONSTANT_DEFINITION(long double, 123.45L)

#undef REAL_CONSTANT_DEFINTION


// File in which `foo` function template is defined

#include "RealConstant.h"

template<class T>
T foo(T x)
{
    return RealConstant<T>::value / x;
}
//realcontent.h
模板
类实常数
{
公众:
静止的
常量真实值;
};
#定义实数\常数\声明(实数)\
模板\
常量实实常量::值;
实常量声明(浮点)
实数常量声明(双精度)
实数常量声明(长双精度)
#未定义实数常量声明
//RealConstant.cpp
#包括“realcontent.h”
#定义实数\常数\定义(实数、常量值)\
模板\
const Real realcontent::value=constantValue;
实常数定义(浮点,123.45f)
实常数定义(双精度,123.45)
实常数定义(长双精度,123.45L)
#未定义实常数定义
//在其中定义“foo”函数模板的文件
#包括“realcontent.h”
模板
T foo(T x)
{
返回realcontent::value/x;
}

当然,实际上并不需要宏。

我将从文本中初始化常量
T

template<class T>
T foo(T x)
{
  const T magic = 123.45;
  return magic / x;
}
模板
T foo(T x)
{
常数T魔法=123.45;
返回魔法/x;
}
它同时比
static\u cast
更明确、可读性更强,更重要的是,它让您有机会用适当的名称记录魔法数字;)

一个简单的

template<class T>
T foo(T x)
{
  return T(123.45) / x;
}
模板
T foo(T x)
{
返回T(123.45)/x;
}

这将允许自定义数字类接受构造函数中的值。

“指出123.45应为T类型的最现代方式是什么?”将
T
替换为
double
@juanchopanza:基于
long double
与“现代”体系结构上的
double
具有相同的精度,你是说?@SteveJessop基于