2014-02-25 27 views
3

我有一些代码,用一个整数乘以一个枚举:在C++乘以一个枚举

QuantLib::Date date2 = date + 12 * QuantLib::Months; 

凡QuantLib ::月被定义为:

enum TimeUnit { Days, 
       Weeks, 
       Months, 
       Years 
}; 

这使我所期望的结果date2约会一年。但是,我无法理解这是如何实现的。

我原以为这不会编译。现在我觉得我到达了一个“十二个月”的对象,然后由QuantLib :: Date'+'操作符重载,但我从来没有见过这种风格。

我来自C#背景,所以可能有些东西我不知道在这里工作。任何人都可以解释发生了什么?任何参考文件将不胜感激。

+0

没有什么都枚举隐式转换和操作符重载奇怪。你最好检查所有参与,因为代码确实个月转换为2,虽然你可能会看到导致date2的增加为1年,但它是如何实现的可能含有一些惊喜 – AlexT

+1

不要相信金融工程师的方式 - 他们通常很聪明家伙,但允许肮脏的技巧。我刚刚意识到,那些家伙重载运算符*为枚举TimeUnit - 好笑话 – AlexT

回答

4

以下内容之一是在效果这里:

  1. 在C++中,枚举类型可以隐式转换为整型。如果发生这种情况,date + 12 * QuantLib::Months将与date + 12 * 2相同。

  2. 也可以为枚举类型重载操作符。在这种情况下,库可能会定义一个operator* (int, QuantLib::TimeUnit),它返回的内容与您正在执行的+兼容。

我不知道QuantLib,但我猜#2是发生了什么事。 QuantLib documentation corroborates this(感谢@DaliborFrivaldsky的链接)。

+0

但OP引用了枚举类型的定义,而这似乎排除2.任何操作符重载? –

+0

它必须是第二项,就像我使用日期+ 12 * 2一样,我会得到不同的结果+ 12 * QuantLib :: Lib。 –

+3

它的情况下数2 - http://quantlib.org/reference/namespace_quant_lib.html,搜索TIMEUNIT,发现第二基准是模板的声明<类型名T>时期运算符*(T N,TIMEUNIT单位) –

1

默认情况下,所有枚举基本上都是整数常量,并且所有整数值都可以在算术表达式中使用。

在您的情况下,常数QuantLib::Months的值为2,因为枚举从零开始并且只是增加。


但是,除非你有使自己的数据/时间的功能,我建议你使用the standard library <chrono> header(或Boost chrono提供的功能,如果你没有一个C++ 11能够编译器/库)。它具有内置的所有这些功能。

这类似于你的代码

auto now = std::chrono::system_clock::now(); // The current time at the moment 
auto then = now + std::chrono::hours(24 * 365); 

变量then现在将在未来小时从now一个例子。

+0

这意味着,如果我用date2 = date + 24替换我的代码,我会达到相同的结果?但我不知道。 –

+0

QuantLib通过此代码库运行,因此我暂时将与它一起工作。 –

+0

@Joachim Pileborg C++中没有这样的默认规则。枚举器的类型是枚举的基础类型。 –

0

在你的例子中,你正在使用所谓的unscoped枚举。每个枚举都有一个基本的整型(这不是必需的,类型为int C++中没有用于枚举的默认规则)。 根据第4.5段。C++标准的3(你问一些参考文献):

3无作用域枚举类型,其基础类型是 不固定(7.2)的prvalue可以被转换为第一的 的的prvalue以下类型的可表示枚举 (即,如在7.2节中描述的范围内BMIN的值,以BMAX)的所有值:整数, 无符号整型,长整型,unsigned long int类型,长长整型或unsigned 长长整型。如果该列表中没有任何类型可以表示枚举的所有值,则可以将非范围枚举类型 的前值转换为扩展整数类型的前值,其中最大值为 整数转换等级(4.13)大于等级在 长的长,可以表示枚举的所有值。如果 是两种这样的扩展类型,则选择签名的类型。

所以在你的例子中QuantLib::Months被转换为int,因为枚举的所有值都可以存储在int类型的对象中。然后通常的算术转换在乘法运算中执行。