评估流运营商>>作为布尔值

时间:2017-01-10 08:11:24

标签: c++ c++11 visual-c++ type-conversion language-lawyer

以下代码在Visual Studio 2008中编译,但在Visual Studio 2013及更高版本中失败。

if (!(ss >> f))
    std::cout << "Parse error\n";

错误消息是

  

错误C2678:二进制'==':找不到左侧的操作符   'std :: basic_istream&gt;'类型的操作数(要么   没有可接受的转换)

并通过以下更改成功修复:

ios

我不太了解这一点。我的问题是,涉及哪些运算符或强制转换或可能operator==标志允许将流读取首先作为布尔值进行求值,然后为什么缺少$T1 = @() $O365Users = Get-MsolUser -All ForEach ($O365User in $O365Users) { $ADuser = Get-ADUser -Filter { UserPrincipalName -eq $O365User.UserPrincipalName } -Properties whenCreated, Enabled, lastlogondate $O365Stats = Get-MailboxStatistics $O365User.DisplayName -ErrorAction SilentlyContinue $O365Smtp = Get-Recipient $O365User.DisplayName -ErrorAction SilentlyContinue If ($O365Stats -and $O365Smtp) { If (($ADUser.Enabled -eq $true) -and ($O365User.isLicensed -eq $true)) { $T1 += New-Object psobject -Property @{ CollectDate = $(Get-Date); ADUserUPN = $($ADUser.UserPrincipalName); O365UserUPN = $($O365User.UserPrincipalName); ADUserCreated = $($ADUser.whenCreated); ADUserEnabled = $($ADUser.Enabled); ADLastLogonDate = $($ADUser.LastLogonDate); O365Licensed = $($O365User.isLicensed); O365LastLogonTime = $($O365Stats.LastLogonTime); O365SMTPAddress = $($O365Smtp.PrimarySMTPAddress) } } } } $T1 = $T1 | Sort-Object -Property ADUserCreated $T1 | Format-Table $T1 | Export-Csv -Path $OutputFile -NoTypeInformation Write-Host "Output to $OutputFile" 会破坏它?

1 个答案:

答案 0 :(得分:16)

自C ++ 11以来,有两种行为发生了变化。

  1. std::basic_ios::operator bool的行为发生了变化。

    operator void*() const;         (1) (until C++11)
    explicit operator bool() const; (2) (since C++11)
    

    注意,因为C ++ 11 operator bool()被声明为explicit;但对于if ((ss >> f) == false)ss(即(ss >> f)的返回值)需要隐式转换为bool(与false进行比较),这是不允许。

  2. 空指针常量的定义已更改。

    在C ++ 11之前operator void*()可以使用而且它不是explicit(在C ++ 11之前没有这样的explicit user-defined conversion),之前C ++ 11 the null pointer constant定义为:

      

    整数类型的整数常量表达式rvalue,其值为零   (直到C ++ 11)

    表示false可以用作空指针常量。因此,ss可以隐式转换为void*,然后与false进行比较(作为空指针)。

    从C ++ 11开始,空指针常量定义为:

      

    值为零的整数文字或类型为std::nullptr_t的prvalue   (自C ++ 11起)

    false不再;它不是integer literal

  3. 因此,由于这两个变化,if ((ss >> f) == false)在C ++ 11及更高版本中不起作用。

    另一方面,if (!(ss >> f))工作正常,因为它有std::basic_ios::operator!(在C ++ 11之前和之后)。

    bool operator!() const;
    
         

    如果关联流上发生错误,则返回true。   具体而言,如果在true中设置了badbit或failbit,则返回rdstate()

    BTW:自C ++ 11以来,即使没有std::basic_ios::operator!explicit operator bool() const也可以使if (!(ss >> f))运作良好,因为在contextual conversion的上下文中,{{1}考虑用户定义的转换;即explicit可以在上下文中转换为ss bool