C++ 是";if(getline(fin,str)){};符合C++;11标准?

C++ 是";if(getline(fin,str)){};符合C++;11标准?,c++,c++11,type-conversion,iostream,explicit-conversion,C++,C++11,Type Conversion,Iostream,Explicit Conversion,我检查了C++11标准,发现了以下事实: std::getline(fin,str)返回一个basic_ios对象,该对象的类具有成员函数显式运算符bool()const 类basic_ios没有成员函数operator void*()const在C++11之前 因此,我认为if(getline(fin,str)){}不符合标准。它应该写为 if(bool(getline(fin,str)){}(但是,VC++2012对此用法给出了警告,即强制void*到bool) 我说的对吗?代码是一致的。当

我检查了C++11标准,发现了以下事实:

  • std::getline(fin,str)
    返回一个
    basic_ios
    对象,该对象的类具有成员函数
    显式运算符bool()const

  • basic_ios
    没有成员函数
    operator void*()const在C++11之前

  • 因此,我认为
    if(getline(fin,str)){}
    不符合标准。它应该写为

    if(bool(getline(fin,str)){}
    (但是,VC++2012对此用法给出了警告,即强制void*到bool)


    我说的对吗?

    代码是一致的。当对象被自动用作条件时,将调用显式转换运算符到
    bool
    。标准的更改旨在保持相同的用法,同时使其更安全。

    David是正确的,以下是支持他的引号。在§12.3.2/2中,St安达尔说

    转换函数可以是显式的(7.1.2),在这种情况下,它仅被视为 直接初始化的用户定义转换(8.5)。否则,用户定义转换 不限于在赋值和初始化中使用。[示例:

    -[结束示例]

    发生此上下文转换的某些位置是操作数到
    、操作数到
    &&
    、以及
    if
    的条件

    因此,直接初始化可以使用显式转换运算符,,在§4/3中

    表达式e可以隐式转换为类型
    T
    当且仅当 对于某些人来说,声明的格式很好 变量t(8.5)。某些语言结构要求 表达式不能转换为布尔值。表达式e出现 在这样的上下文中,被称为上下文转换为bool,是 格式良好当且仅当声明
    bool t(e);
    格式良好
    , 对于一些发明的临时变量
    t
    (8.5)


    如您所见,该标准规定了上下文转换的直接初始化,这就是为什么显式转换在
    if
    条件下工作。

    显式运算符bool
    (并且仅
    显式运算符bool
    )具有特殊语言,允许在某些情况下隐式转换为
    bool
    。此转换的规范语言为“上下文转换为
    bool

    这些是语言进行布尔测试的地方。
    if/while/for
    使用的条件表达式是“上下文转换为
    bool
    ”。逻辑运算符和条件运算符(
    ?:
    )也是如此

    所以,虽然你不能做到这些:

    bool b = std::getline(fin, str);
    void func(bool) {}
    func(std::getline(fin, str));
    
    while(std::getline(fin, str)) {...}
    for(;std::getline(fin, str);) {...}
    if(std::getline(fin, str) && somethingElse) {...}
    
    您可以执行以下操作:

    bool b = std::getline(fin, str);
    void func(bool) {}
    func(std::getline(fin, str));
    
    while(std::getline(fin, str)) {...}
    for(;std::getline(fin, str);) {...}
    if(std::getline(fin, str) && somethingElse) {...}
    

    你应该知道VC++2012仍然将其实现为
    操作符void*
    。这就是警告的原因。每当你认为需要编写“
    if(bool(…)
    ”时,某个地方出现了可怕的错误。