使用编译时常量整数的浮点计算是在编译时还是在运行时执行的?例如,何时是以下式计算除法运算:
template <int A, int B>
inline float fraction()
{
return static_cast<float>(A) / B;
}
答案 0 :(得分:2)
对于这么简单的事情,编译器可能在编译时执行此操作。事实上,编译器可能在编译时甚至没有模板,只要在编译时知道所有值:即如果我们有inline float fraction(int A, int B)
,它可能会执行如果我们拨打fraction(1,2)
,则在编译时划分。
如果你想强制编译器在编译时做一些东西,你将不得不使用一些模板元编程技巧,而且我不确定你是否可以让它与浮动一起工作 - 点算术。但这是该技术的一个基本示例:
// Something similarly simple that doesn't use floating-point ;)
template <int A, int B>
struct Product {
enum { value = A * B };
};
// Later:
... Product<3, 4>::value ...
答案 1 :(得分:1)
最好的办法是查看生成的代码 - 不能保证在编译时会执行浮点运算,但可能会在更高的优化级别执行,特别是对于像这样简单的事情。
(有些编译器可能会避免这样做,因为对于某些体系结构,浮点行为在运行时是可配置的。在编译时执行的操作的结果可能与运行时执行的相同操作的结果有所不同。)
答案 2 :(得分:1)
您应该等待具有C ++ 0x constexpr关键字实现的gcc 4.6。
答案 3 :(得分:1)
我认为它是实现定义的,但大多数编译器将在编译时评估常量表达式。但是,即使您没有进行以下修改:
template <int A, int B>
inline float fraction()
{
static const float f = static_cast<float>(A) / B;
return f ;
}
如果在运行时计算表达式,将至少确保表达式仅被计算一次。
答案 4 :(得分:1)
C或C ++标准都不需要在编译时评估任何条带的常量表达式,但它们允许它。在过去20年中发布的大多数编译器都将评估算术表达式,因此如果不进行函数调用或内联代码很重要,请尽可能简单。
如果这些表达式的范围仅限于单个文件,则为方便起见,您始终可以利用预处理器和#define FRACTION(a,b) (float(a)/float(b))
。我不建议在标题中执行此操作,除非您有一个好的方案来防止污染任何#include
的文件。