当输入实数时,是否可以保证复杂的<type>对象的虚部被设置为零?

时间:2018-03-21 13:27:31

标签: c++

在我的环境(g ++ 5.4.0)中,代码

complex<double> cmp;
cin >> cmp; //input 3 or (3) (not (3,0))
cout << "cmp = " << cmp << "\n";

给我结果:

cmp = (3,0) //imaginary part is automatically set to 0

有没有人有书面证据证明这种行为? N4140(§26.4.6-12;第921页)说

 Effects: Extracts a complex number x of the form: u, (u), or (u,v), 
          where u is the real part and v is the imaginary part (27.7.2.2).

但这并不意味着表单u(u)的输入会使对象的虚部成为0

您可以在可靠的MSDN示例(https://msdn.microsoft.com/ja-jp/library/mt771459.aspx#operator_gt__gt_)中看到此行为,但即使这样也无法明确解释。

草案说“u是真实的部分”,我只输入真实部分。我认为决定将什么样的价值设定为虚构部分存在歧义。当然,u的虚部是0,但我认为这没有任何保障。

2 个答案:

答案 0 :(得分:2)

标准的意图可能是它应该有效,即使审查时的文本没有明确说明。实际上,代码将与已知的实现一起使用。

现有缺陷报告要求委员会澄清其意图 已实施的内容:

#2714 complex stream extraction underspecified

答案 1 :(得分:1)

如果你看一下实现(https://gcc.gnu.org/onlinedocs/gcc-4.6.3/libstdc++/api/a00812_source.html

00486   template<typename _Tp, typename _CharT, class _Traits>
00487     basic_istream<_CharT, _Traits>&
00488     operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
00489     {
00490       _Tp __re_x, __im_x;
00491       _CharT __ch;
00492       __is >> __ch;
00493       if (__ch == '(') 
00494     {
00495       __is >> __re_x >> __ch;
00496       if (__ch == ',') 
00497         {
00498           __is >> __im_x >> __ch;
00499           if (__ch == ')') 
00500         __x = complex<_Tp>(__re_x, __im_x);
00501           else
00502         __is.setstate(ios_base::failbit);
00503         }
00504       else if (__ch == ')') 
00505         __x = __re_x;
00506       else
00507         __is.setstate(ios_base::failbit);
00508     }
00509       else 
00510     {
00511       __is.putback(__ch);
00512       __is >> __re_x;
00513       __x = __re_x;
00514     }
00515       return __is;
00516     }

您可以看到,s(s)是您在键盘__x上键入的格式,您的复合体会被分配到__re_x(或者第505或513行,为简单起见,我们可以将其视为double

快速查看operator=会告诉您虚部是默认构造的。

00230     complex<_Tp>::operator=(const _Tp& __t)
00231     {
00232      _M_real = __t;
00233      _M_imag = _Tp();
00234      return *this;
00235     } 

这意味着您唯一的保证是假想部分将默认构建(在GCC上)。对于大多数类型,这会转换为0已初始化。