【问题标题】:Why can I have a ratio object in C++为什么我可以在 C++ 中有一个比率对象
【发布时间】:2014-07-28 22:12:59
【问题描述】:

我正在学习 C++11 中的 ratio。根据cplusplus.com 和Professional C++ 2nd 一书(以下段落是其中的摘录)。

有理数的分子和分母表示为 std::intmax_t 类型的编译时间常数。因为编译 这些有理数的时间性质,使用它们可能看起来有点 复杂且与平常不同。您不能定义比率对象 与定义普通对象的方式相同,并且不能调用方法 在上面。您需要使用typedefs

这意味着我必须写

typedef ratio<1,3> one_third;

而不是

ratio<1,3> one_third;

但我发现这两种写入比率的方式都有效。我可以使用.:: 访问比率成员。

问题一、cplusplus.com和Professional C++书错了吗?

以下 sn-p 来自 cplusplus.com 示例。

typedef std::ratio<1,3> one_third;
typedef std::ratio<2,4> two_fourths;
typedef std::ratio_add<one_third,two_fourths> sum;
std::cout << sum::den << std::endl;

问题 2。但是,我遇到了一个错误(使用 VS 2012)

error C2039: 'den' : is not a member of 'std::ratio_add<_R1,_R2>'

根据 cmets,使用typedef ratio_add&lt;one_third, two_fourths&gt;::type sum 更便携。

【问题讨论】:

  • 我认为你想使用#define 而不是typedef
  • @Havenard 我看不出#define 在这方面有什么优势,而且通常的缺点是众所周知的,我希望我不需要在这里提及它们。为什么你认为#define 会更好?
  • 代码很好,也许你的标准库实现不是。见ideone.com/4nKryf
  • @champaign 这是 VS2012 bug,因为该版本不支持别名模板。已在 VS2013 中修复。

标签: c++ c++11 chrono


【解决方案1】:

您不必必须使用typedefs,但正如书中所说,&lt;ratio&gt; 处理编译时数学,其中定义的元函数采用类型模板参数。

如果您不使用typedef,您将创建一个名为one_thirdstd::ratio&lt;1,3&gt; 实例,它不适合作为类型参数传递。在这种情况下,您需要使用 decltype 来获取可以传递给 ratio_add 的适当类型

std::ratio<1,3> one_third;
std::ratio<2,4> two_fourths;
std::ratio_add<decltype(one_third), decltype(two_fourths)> sum;
std::cout << decltype(sum)::den << std::endl;

Live demo


您看到的错误消息是因为缺少对别名模板的支持,ratio_add(和其他类似的元函数)实现是not standard conforming on VS2012。如链接的错误报告中所述,解决方法是使用嵌套类型type

typedef std::ratio_add<one_third,two_fourths>::type sum;
std::cout << sum::den << std::endl;

【讨论】:

  • 谢谢。您的代码适用于 ideone.com/。但是在 VS 2012 中生成错误 error C2039: 'den' : is not a member of 'global namespace'` 和 error C2226: syntax error : unexpected type 'std::ratio_add&lt;_R1,_R2&gt;'。我认为我应该更好在我的代码中使用 &lt;ratio&gt; 作为类型而不是对象。
  • @champaign IIRC VS2012 还有一个错误,不允许您在 decltype 表达式之后使用 ::whatever。这可能就是您遇到的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-30
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-27
相关资源
最近更新 更多